Giter Site home page Giter Site logo

discussions's People

Contributors

jonathanong avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

isabella232

discussions's Issues

ctx.req.on and ctx.req.pipe limitations ?

I made a micro web app so I can record my voice anywhere I want. At first I thought it was working perfectly but only to realize the long recordings were trimmed at the end. So I opened up my project again and tried to understand what was going on.
I noticed the trimmed recordings had a maximum size of 128K. But the POST data (which is sent in plain format btw) was transmitted by full length. After few experimentation I determined the problem was the piping :

const fileStream = fs.createWriteStream('path/to/file.wav');
ctx.req.pipe(fileStream);

If I change to

const fileData = '';
ctx.req.on('data', function (data) {
  fileData += data;
});
ctx.req.on('end', function () {
  fs.writeFileSync('path/to/file.wav', fileData);
});

It works. But I'd like to understand why the former doesn't wait all the data to be piped in. What do you think ?

Also because I don't like how the latter save all this raw data in the form of a string in a variable before filling up the file container.

Thanks in advance.

[koa-compress] Using this library adds 200+ ms to content download time

I've noticed that when I use this library, the "Content Download" time in Chrome dev tools is increased by 200+ ms. I see the same thing in Firefox for the "Receiving" time. I've created a small test script to isolate this issue from anything else:

const Koa = require('koa');
const app = new Koa();

app.keys = ['key1'];
app.use(require('koa-compress')({
  flush: require('zlib').Z_SYNC_FLUSH
}));

let data = [];
for(let i = 0; i < 50000; i++) {
  data.push('hello');
}
app.use(async (ctx, next) => {
  ctx.body = data;
});
app.listen(3000);
console.log('Listening on port 3000.');

This is using Koa v2, koa-compress v2.0, Node v7.2.1 along with the harmony flag.

With compression on, the page loads between 200-230 ms. Transferred amount is 637B.
With compression off, the page loads between 8-30 ms. Transferred amount is 390.63KB.

It looks like compression is working fine, but why is it adding 200 ms?

I'm running these tests inside a local Ubuntu vagrant environment.

Hosting mp3 file

I'm coding API server to be used in mp3 app.
I've used koa-send, koa-static, and just setting mp3 file to response-body.

But, no matter what API the app uses, the app stops. When I sent the length of the MP3 file separately because the app did not seem to accept the length of the MP3 file, it worked on iOS but not on Android.

If I post the same MP3 file on S3 and send request to that URL, it worked well, so I can't understand what the problem is.

Also, if I play music on Safari using my API, it comes out as a live broadcast. (using other sites, it comes in the form of mp3)

If it's a problem that you don't know how long it's playing, why is it the same file, but not on other sites, and not on my API?

Other storage site:

other storage site

My API:

my API

404 not found for everything

This library doesn't work with the examples given.

Something as simple as

const serve = require('koa-static');

async function images(ctx, next) {
  await next();
  serve('public/images/preview/');
}

app.use(images)

And try to visit localhost:3000/1.png Not found. Please improve the documentation.

Cannot make middleware to coerce type of query parameter

The problem is that query serialized back to string in setter, so I cannot write middleware that will convert some parameters to number, and I have to do it only in handler, which is inconvenient :(

cast @dead-horse

I need to be able to modify it, for coercion of validated data.

Improving the Koa ecosystem by moving all Koa modules to the koajs organization!

With GitHub's new organization administration, I want to try moving all koa middleware/plugins to the org. The goals are:

  • To have shared maintenance of all code.
  • Have all middleware/plugins be in one location.
  • Create teams so everyone knows who to ask for help.
  • Allow members to create repos within the organization.

I'm not sure how this will work. I remember last time, you had to be an owner of the organization for you to transfer a repository to an organization.

The steps will be something like:

  • Let us know what repository you'd like to transfer
  • We'll create a team for that repository if there isn't one yet
  • We'll add that repository to that team
  • We'll add you to that team

If anything, just transfer the repository to me and I'll add it to the organization. Comment here so I remember to add it to the organization! Let me know if anyone wants to transfer any repositories.

First one i'd like to transfer is koa-convert :)

NOTE: IF YOU'RE IN THIS ORGANIZATION, PLEASE SETUP 2-FACTOR AUTHENTICATION!

Who is using Koa?

I notice there is not a page describing who is using the framework? Any idea of some "big companies" using it? Thanks

Respond to Koa request immediately, continue middleware chain

I am writing the middleware for API endpoints in my app that respond to webhooks from other applications, and am relatively new to Koa, so am not completely familiar with its patterns.

I would like to structure my middleware as follows:

exports.updateReceived = async (ctx, next) => {
  // Respond to server issuing the webhook
  ctx.res.body = "ok";
  ctx.res.statusCode = 200;

  // Grab what we need from the request
  const { headers, state, request } = ctx;
  const { body } = request;

  // Do some async work
  const { example } = await doSomeAsyncWork(ctx);

  // Prepare a database query
  const query = { aValue: anId };

  // Run the DB query
  const result = await Thing.findOne(query);

  // Add data to the request
  state.thing = result;

  // Move on...
  return next();
};

However, this does not appear to be working, as an error in any of my async methods can cause the route to error out.

My goal is for this endpoint to always respond "yep, ok" (immediately), meaning it is simply up to the application to handle any error states.

I have researched this fairly well, and have come across this pattern:

app.use(async ctx => {
  db.fetch() // Assuming a Promise is returned
    .then(() => { ... })
    .catch(err => {
      log(err)
    })

  // status 200 will be returned regardless of if db.fetch() resolves or rejects.
  ctx.status = 200
})

However, this does not meet my needs as the middleware makes no use of next, so it is not really a useful pattern, so far as I can tell.

Could someone tell me what I am overlooking? I wrote this question on StackOverflow several days ago, but getting nowhere.

koa-static: heavy caching issue

I am trying out Koa for a simple app. I have used koa-static as a middlewear to serve the /public directory.
Middlewear works fine.

To run the app, I push the application to a local docker container. When running the app I found out that it caches the static files completely. Even if i completely remove entire directories it still serves those js/html files. Even a server restart doesn't seem to clear cache. Is it because koa-static may be keeping a separate set of files for cache delivery? Later I tried adding koa-no-cache to middlewear. But still doesn't seem to work.

I am not sure whether this is koa-static issue or something to do with Docker.

Why Koa ctx.body not working in if statement?

I am trying to create a post RestApi in node with koa and postgresql. I have a unique email validation and want to check if email exists the it should display message user already exists with this email. My query is working but that ctx.body not working. This api is creating new user every time. It should display msg "User already exists with this email" when email exists in db. Why my ctx.body not working?

router.post('/createNewUser', async (ctx) => {

    var name = ctx.request.body.name;
    var email = ctx.request.body.email;
    var password = ctx.request.body.password;

    if (
        !name ||
        !email ||
        !password
    ) {
        ctx.response.status = 400;
        ctx.body = {
            status: 'error',
            message: 'Please fill all the fields'
        }
    } else {

        await ctx.app.pool.query("SELECT * FROM users WHERE email = $1",
                [`${email}`],
            (err, result) => {
            if(result.rows.length > 0){
                ctx.body = {
                    exceptions: "",
                    status: 200,
                    error: false,
                    message: "user already exists with this email",
                };
            }
        });

        await ctx.app.pool.query(`INSERT INTO USERS (name,email,password) VALUES ('${name}','${email}','${bcrypt.hashSync(password, 10)}')`);
        const {rows} = await ctx.app.pool.query("SELECT * FROM users ORDER BY id DESC LIMIT 1");

        ctx.body = {
            exceptions: "",
            status: 200,
            error: false,
            message: "User registered Successfully",
            data: rows[0],
        };
    }
});

Express / Connect interoperability / compatibility

Related issues from the graveyard: koajs/koa#71, koajs/koa#74

I kind of expected to be able to mount a koa app in an express app.

You currently can only do the following:

expressApp.use('/some-path', koaApp.callback());

But this then fully takes over /some-path. There is no way to call next in the koaApp and yield back to the expressApp.

Do you think this is a feature that we could and should support?

koajs/conditional-get: uws.http failure

this is not really issue of this module but for completeness

const http = require('uws').http
const Koa = require('koa')
const conditional = require('koa-conditional-get')

const app = new Koa()

app.use(conditional())

app.use(ctx => {
    ctx.body = 'Hello World!'
})

http.createServer(app.callback()).listen(8000)

using this module with uws http server results in:
Warning: req.headers usage past request handler is not supported!

this is because this.get (or this.headers in fresh module) being called in upstream triggers it

one would have to "solve" this like

const fresh = ctx.fresh
return next().then(() => {
          if (fresh) {
        ctx.status = 304;
        ctx.body = null;
     }
    });

which I don't think is really a solution since one has to allocate memory before it is sure it will get used
I suspect there is bunch of other libraries that will have the same "issue"

reported that over to uws
https://github.com/uWebSockets/uWebSockets/issues/590

Either 404 or wrong content

Update: on Linux server it happens too.

I'm trying to figure out how to use koa-static (in SPA) properly.

First I just had put it in front of the other middleware, hoping that when it finds a file it would immediately return serving it:

const   Koa = require('koa')
    ,   app = new Koa()
    ,   static = require('koa-static')
app.use(static('css'))
app.use(static('img'))
app.use(static('js'))
app.use(my-other-middleware)
...
app.listen(32123)

But my-other-middleware rewrites the response (e.g. any css file has the same contents - of the main page). So I try to put an alternate route like this:

my-other-middleware = async (ctx, next) => {
    switch (ctx.url.substr(0, 4)) {
        case '/css':
        case '/js/':
        case '/img':
            return
            // or return next()
            // or next(); return — nothing helps
    }
...
}

So, for the "static" directories the response shouldn't get rewritten. But then I get 404 'Not Found' for any file which actually exist — e.g.

http://localhost:32123/css/a.css
http://localhost:32123/js/main.js
...

I don't even know how to debug it. Am I doing something wrong, or maybe it's just some incompatibility in my software stack? Bear with a noob question please.

Thank you.

Immutable empty query obj

console.log(ctx.query)
if (!ctx.query.sort) {
  ctx.query.sort = '-createdAt'
}
console.log(ctx.query)

Will yield {} and {} but if I pass anything in qs I correctly get {foo:'bar'} and {foo:'bar', sort: '-createdAt'}

[koa-compress] weird memory leak

I found a weird problem. We have a server-rendered service. When we were stress testing, it was normal for 100 qps, but when we set http Connection:keep-alive. There was a significant memory leak after 4 minutes and 1GB of memory in 8 minutes. We have been looking for a long time because this phenomenon disappeared after removing the koa compress middleware. I read the koa compress source, but it seems that there is nothing unusual. Can you explain it to me?thank you very much.

Question on inheriting Koa

I wanted to inherit Koa in TypeScript to add a few properties and methods to Context because adding by using prototype does not support the auto-complete for the editor. But an error occurred when calling super.

Here's my code:

import * as Koa from "koa";

class App extends Koa {
    constructor() {
        super();
        this.use(compose([error]));
    }
}

const app = new App();

Here's the error:

 TypeError: Class constructor Application cannot be invoked without 'new'

I tried just import Application from Koa, but the same error occurred.

Mention koa-router & friends

Hi there!

I like koa and its paradigms, but as a used-to-express user I was severely wondering how it's possible that there is no app.get() or app.post(). I then realized that I need koa-router for that.

Unfortunately the website / readme doesn't mention koa-router or other important middlewares like koa-body at all. Even grepping for "router" did not yield a single match.

Would be quite helpful for newbies to link to the most popular middlewares in a prominent place 😉

Hosting mp3 file

I'm coding API server to be used in mp3 app.
I've used koa-send, koa-static, and just setting mp3 file to response-body.

But, no matter what API the app uses, the app stops. When I sent the length of the MP3 file separately because the app did not seem to accept the length of the MP3 file, it worked on iOS but not on Android.

If I post the same MP3 file on S3 and send request to that URL, it worked well, so I can't understand what the problem is.

Also, if I play music on Safari using my API, it comes out as a live broadcast. (using other sites, it comes in the form of mp3)

If it's a problem that you don't know how long it's playing, why is it the same file, but not on other sites, and not on my API?

Other storage site:

other storage site

My API:

my API

Internal sub-request

Dear Koa devs,

Super happy with Koa. We've been using it for over a year.

I'm facing an issue where I want to do an 'internal subrequest'. What this means is that a real HTTP request comes in, and I want to write a middleware that creates a brand new (fake) HTTP request and return the result.

This middleware will then take the result and do some post-processing before returning it.

Is there a standard way to solve this problem with Koa? I want to avoid doing a 'real' HTTP request on the local server, because it seems like a lot of overhead. I don't really want to invoke the TCP/HTTP stack, although my prototype does use that approach.

Any pointers here are welcome!

Koa as a generic middleware solution?

The repository description reads:

Expressive middleware for node.js using ES2017 async functions

The first human-readable line of the readme reads:

Expressive HTTP middleware framework for node.js to make web applications and APIs more enjoyable to write.

Essentially the package is a class wrapper around koa-compose, allowing the composition and execution of a middleware stack on request from an HTTP server.

But why only HTTP? Is this pattern not applicable to many request+response services?

Why?

Middleware offers a functional solution to working with requests+responses services, giving developers a tool to reuse common context manipulation & comparison and assert the cleanliness of context (by early stack termination), making it an ideal container for business logic. The current nature of Koa makes it inapplicable to other request+response services common to a stack that might contain Koa and benefit from standardized request+response and common logic for other services.

Why Koa?

Admittedly, there are several other middleware composition alternatives available, including koa-compose, that could just as easily be wrapped in a class and attached to an emitter. Sure, this is true, but the active nature of the Koa ecosystem makes it an ideal platform to offer standardized middleware support for request+response environments. The value of being able to offer some level of standardization to various environments with a functional component that is so flexible is very appealing to me, and I would hope to developers at large.

What would need to change?

As I see it, Koa could easily become service-agnostic while maintaining it's existing functionality as an HTTP server utility in several ways. Some less awesome than others.

Constructor Configuration

The easiest & cleanest option, in my opinion, is to enable a constructor configuration supporting the following or similar properties:

new Koa({
  provider: (callback, args) => { // Callback being the output of this.callback() from listen()
    const server = http.createServer(callback); // Allows one to connect Koa to the emitter
    return server.listen(...args); // Args provided to the listen() method as usual
  },
  onRequest: (args) => { // Agnostic context assembly, provided all args from callback
    return {
      // Service-specific context assembly
      // Implement createContext by default
      // 404 defaults, etc... previously handled in createContext
      // Perhaps an internal/immutable context could be created here and shared with the response?
    };
  },
  onResponse: (ctx) => { // One last method to call when the stack is finished executing
    // for HTTP, this would essentially be the respond() method in lib/application.js
  }
})

This solution assumes that the call to createContext in the callback method is replaced with a reference to onRequest, which would return the initial context object. It also assumes that the handleRequest method pass the context to onResponse after stack execution (which is where the statusCode would be assumed, errors handled, and on-finished implemented for HTTP).

Default parameters could be assigned to this configuration with spread assignment, allowing the class to work out of the box with HTTP support from an external package. Perhaps the class wrapper could/should be abstracted to another package, i.e. koa-app.

I would even consider removing onRequest and onResponse altogether and providing the parameters given to the callback to the middleware, allowing middleware to assemble the request and become responsible for the response.

At any rate, I just wanted to share my thoughts on the matter and see what the community feedback is. If this is a direction that the community is open to exploring, I would be happy to submit a PR.

Errors not caught when using "common" sync functions - consider forcing async

The docs currently state that Koa supports "common" functions as well as the new async/await. While this works with happy path code, it falls apart with error handling. Here's an example where my error doesn't get caught:

const Koa = require('koa');
const app = new Koa();

app.use(({response}, next) => {
	try {
		return next();
	} catch (ex) {
		console.log('Gotcha', ex.stack);
		response.body = ex.stack;
	}
});
app.use((ctx, next) => {
	console.log('About to throw');
	throw new Error('Catch me if you can.');
});

Updating the error handler middleware to be async/await fixes the issue:

const Koa = require('koa');
const app = new Koa();

app.use(async ({response}, next) => {
	try {
		return await next();
	} catch (ex) {
		console.log('Gotcha', ex.stack);
		response.body = ex.stack;
	}
});
app.use((ctx, next) => {
	console.log('About to throw');
	throw new Error('Catch me if you can.');
});

This makes sense, but might throw newcomers (see what I did there). If there is no easy solution to this problem, then might I suggest that you advise all middleware to be async? The koa-composer is wrapping all middleware with a Promise already (which is likely the reason why the "sync" error is not caught). Just a personal opinion, but I think it might simplify all things if you advise all middleware to be async/await (easier for newcomers, fewer issues, easier docs, etc).

EDIT: if middleware does not use async/await, then it should return a promise. Failure to do so breaks an app. I think koa could easily warn users if the middleware fails to do one of the above.

EPIPE error occurs when the server returns mp3 file.

I want to play music that received from my server.
it works properly without error when I test it in the local, but EPIPE errors occur when I test it in the server.

const mp3 = fs.createReadStream(`../music-uploader/${low_mp3}`);
ctx.response.set("content-type", "audio/mp3");
ctx.response.set("Accept-Ranges", 'bytes');
ctx.body = mp3;

It is my code and I don't know how to fix it.

  Error: write EPIPE
  at _errnoException (util.js:1022:11)
  at WriteWrap.afterWrite (net.js:867:14)

why it happens???

how to reg two part to the same file

test1
router.use('/test', require('./test').routes(), require('./test').allowedMethods());
/test -->ok
/test2-->404

test2:
router.use(['/test','test2'], require('./test').routes(), require('./test').allowedMethods());
/test -->404
/test2-->404

test3

router.use('/test', require('./test').routes(), require('./test').allowedMethods());
router.use('/test2', require('./test').routes(), require('./test').allowedMethods());

/test->404
/test2-->404

test.js:

var router = require('koa-router')();
router.get('/', async function (ctx, next) {
ctx.body='ok'
})
module.exports = router;

how to make both the /test and /test2 can be accesss

Destroy Mounts

We are using koa-mount to mount a server based on who is logged in. We want to only allow the user that is logged in to see their servers. How can we achieve this? Can we use something like koa-session?

@fl0w becomes @miwnwski

I just wanted to let everybody know that I've switched Github account from fl0w to miwnwski. This was due to me "loosing" the 2FA phone number (long story) the account is connected to and me not saving recovery codes (that's on me).

I still have access to it via an obscure iPhone app (using an API Key) that only allows me to comment on tickets.
If anyone have any questions regarding security or the validity of this account just ask them here.

Why do i need koa-static

I have a few questions: why use it, what problems it solves, and what advantages it has to compare to other

How to exclude api router?

Hi, i want to run a resultful api in Postman,
but i get an error Invalid CSRF token.

How can i exclude my api router from csrf ?

i try to use:

headers: {
  X-CSRF-Token: [csrf-value],
  _csrf: [csrf-value]
}

or

/api/add?csrf=gnwLgVst-Hf-liZtMY3BQwEik9x-Sn4k1-58

but it dosn't work

long streams get randomly broken

This is since the middle of last year - transferring large files on slow connections, I get an error:

Error: You cannot pipe after data has been emitted from the response.

Any chance this gets replaced? always need to monkey patch. Quite annoying.

  Error: You cannot pipe after data has been emitted from the response.
      at Request.pipe (C:\blog\app-ui\node_modules\request\request.js:1478:26)
      at respond (C:\blog\node_modules\koa\lib\application.js:240:43)
      at handleResponse (C:\blog\node_modules\koa\lib\application.js:149:34)

Solution:
Do not use Koa ctx.body = stream. Return the stream directly.
Code here: koajs/koa#944 (comment)

How can I catch EADDRINUSE?

I've tried to wrap listen() in a try...catch but it doesn't actually catch the error. I don't want to print a stack-trace, I want to print a helpful error message. How can I catch this error? I've searched but can't find any other discussions about this problem.

Thanks a bunch for this project!

Backlink: fraction/oasis#129

[koa] Unexpected exit with code 0 during an http request

Our prod deployment of a koa server is exiting several times a day with little info logged. There is logging on a number of node process events including beforeExit, exit, close, uncaughtExceptionMonitor and unhandledRejection but only exit is triggered. None of our code calls exit() explicitly and looking through npm packages we use it doesn't look like any of them would be calling it either.

The exit happens during a request to a specific API PUT endpoint where the body payload is relatively large compared to other calls, but not huge (around 15-30KB). It's not happening consistently on every request, as a server restart and re-attempt with the same data can work in most cases.

Based on log timestamps the exit happens immediately when the request is made. Any exception around these calls would be handled and logged but it looks like no exception is thrown. This issue has happened when our codebase used the co-request library to manage http requests as well as after migrating to axios.

My understanding is that node will exit when there are no pending async operations, which could indicate koa is stopping for some reason?

how to set interval within stream

i use coffeescript rewrite this example.

koa= require 'koa'
route= require 'koa-route'
cors = require 'koa-cors'
app= module.exports= koa()

stream= require 'stream'
class Subscription extends stream.Readable
    constructor: (@options)->
        super
        @value = 0
    _read: ->
        @push(String(@value++))

class SSE extends stream.Transform
    _transform: (data, enc, next)->
        @push 'data: ' + data.toString('utf8') + '\n\n'
        next()

app.use cors()
app.use route.get '/sse', ->
    # otherwise node will automatically close this connection in 2 minutes
    @req.setTimeout Number.MAX_VALUE
    @type= 'text/event-stream; charset=utf-8'
    @set 'Cache-Control', 'no-cache'
    @set 'Connection', 'keep-alive'
    body= @body= new SSE
    stream= new Subscription 'some event'
    stream.pipe body

    yield return

if not module.parent then app.listen 3000

run coffee file.coffee
then listening on port 3000

curl http://localhost:3000/sse

Original output is printed every 1ms, how could i set it every 1s.

Brotli compress is slow

I was just checking out my nodejs service with Brotli compression enabled with default config and Brotli enabled.
Download size decreased from 77kb to 47kb with Brotli, but total request time raised from 209ms (waiting: 200ms + download: 9ms) to 1306ms (waiting 1300ms + download: 6ms) in Chrome DevTools.
I read that latency might increase, but not at such a high level.

Tested with Chrome Dev85, NodeJS 12.18.1 + Koa 2.13 + Koa-Compress 4.0.1.
I am working with JSON data.

Uncaught `TypeError: Cannot read property 'hasHeader' of undefined` error

Stacktrace:

TypeError: Cannot read property 'hasHeader' of undefined
  File "/home/ubuntu/turnout/turnoutapi/node_modules/koa/lib/response.js", line 436, col 28, in Object.has
    return typeof this.res.hasHeader === 'function'
  File "/home/ubuntu/turnout/turnoutapi/node_modules/koa/lib/response.js", line 204, col 14, in Object.get length [as length]
    if (this.has('Content-Length')) {
  File "/home/ubuntu/turnout/turnoutapi/node_modules/koa-logger/index.js", line 77, col 33, in logger
    const length = ctx.response.length
  File "async /home/ubuntu/turnout/turnoutapi/src/error.service.js", line 10, col 9, in null.<anonymous>
  File "async /home/ubuntu/turnout/turnoutapi/src/index.js", line 49, col 9, in null.<anonymous>

Version:

    "koa": "^2.11.0",

Affects:
Doesn't seem to break anything, but gets logged a bunch in my error logging (Sentry)

Request / response aliases are bad idea

I suspect I'll met a disagreement but I have to say it.
Request / Response aliases are very confusing. And I'm not a Koa newcomer.

Why this.body is this.response.body while this.headers are this.request.headers?
this.request.body is used often as well as this.response.headers. Oh, wait, the latter is this.set(...)! Did I tell you it's confusing?

I know, it's optional and I may use full path (as I do). But, the thing is, the library
authors are following the "convention" and create first shortcut-ful then even shortcut-only APIs. Like this.path without a proper copy in this.request.path.

I feel like way too many things are in the single namespace right now.

Koa is mature and established. Why I bother?
Because async-await is in the Node 7.0 and I expect more people will start to adopt this framework soon. Maybe Koa 2 could take an opportunity to clean this up.

Memorizing these tables is not a friendly option

Request aliases

The following accessors and alias Request equivalents:

ctx.header
ctx.headers
ctx.method
ctx.method=
ctx.url
ctx.url=
ctx.originalUrl
ctx.origin
ctx.href
ctx.path
ctx.path=
ctx.query
ctx.query=
ctx.querystring
ctx.querystring=
ctx.host
ctx.hostname
ctx.fresh
ctx.stale
ctx.socket
ctx.protocol
ctx.secure
ctx.ip
ctx.ips
ctx.subdomains
ctx.is()
ctx.accepts()
ctx.acceptsEncodings()
ctx.acceptsCharsets()
ctx.acceptsLanguages()
ctx.get()

Response aliases

The following accessors and alias Response equivalents:

ctx.body
ctx.body=
ctx.status
ctx.status=
ctx.message
ctx.message=
ctx.length=
ctx.length
ctx.type=
ctx.type
ctx.headerSent
ctx.redirect()
ctx.attachment()
ctx.set()
ctx.append()
ctx.remove()
ctx.lastModified=
ctx.etag=

I guess this.request.foobar felt too long to write and you probably didn't want to get this.req confused with native Node Request which is commonly called req. But still this is not worth the encomplication IMO.

ctx.originalUrl invalid when used as express route

When using a Koa app as an express middleware, with a path prefix, the ctx.originalUrl will not be valid and will not contain the path prefix:

const expressApp = express()
const koaApp = new Koa()
const koaRouter = new Router()

koaRouter.get('/test', async (ctx, next) => {
  console.log(ctx.originalUrl) // will not contain "/api"
  ctx.body = { foo: "bar" }
})

koaApp.use(koaRouter.routes())
expressApp.use('/api', koaApp.callback())

This is due to the fact that, behind the scene, the express router will manipulate req.url when the request is being processed by router middleware.

I would suggest that Koa does something similar to what express does when it is itself used as a middleware, meaning preserve the original originalUrl:
https://github.com/expressjs/express/blob/f3fa758af9664526ee18c58764590e48f559e6ae/lib/router/index.js#L172

My suggestion is to change the following line of lib/application.js:

  context.originalUrl = request.originalUrl = req.url;
  // to
  context.originalUrl = request.originalUrl = req.originalUrl || req.url;

Now one can argue that this would be a breaking change, especially because any route defined in koa will need to reflect the prefix again. In my example above, the routes in the router would have to be defined as koaRouter.get("/api/test", ...). That is true, but we also need to consider that the current implementation already breaks the request URL related getters.

Access to XMLHttpRequest at 'https://localhost:3443/images' from origin 'http://localhost:4200' has been blocked by CORS policy

This is my app.js file:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var index = require('./routes/index');
var usersRouter = require('./routes/usersRouter');
var imagesRouter = require('./routes/imagesRouter');
const uploadRouter = require('./routes/uploadRouter');

const Images = require('./models/images');




//const uploadRouter = require('./routes/uploadRouter');
//const favoriteRouter = require('./routes/favoriteRouter')
var config = require('./config');

const mongoose = require('mongoose');
//mongoose.set('useCreateIndex', true);
mongoose.Promise = require('bluebird');

var passport = require('passport');
var authenticate = require('./authenticate');

// Connection URL
const url = config.mongoUrl;
const connect = mongoose.connect(url, {
    //useMongoClient: true,
    /* other options */
     useNewUrlParser: true ,
     useUnifiedTopology: true 
  });

connect.then((db) => {
    console.log("Connected correctly to server");
}, (err) => { console.log(err); });

var app = express();

// Secure traffic only
app.all('*', (req, res, next) => {
  if (req.secure) {
    return next();
  }
  else {
    res.redirect(307, 'https://' + req.hostname + ':' + app.get('secPort') + req.url);
  }
});

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));



app.use(passport.initialize());

app.use('/', index);
app.use('/users', usersRouter);


app.use(express.static(path.join(__dirname, 'public')));

app.use('/images',imagesRouter);
app.use('/imageUpload',uploadRouter);


// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

And this is my `cors.js` file: 

const express = require('express');
const cors = require('cors');
const app = express();

const whitelist = ['http://localhost:3000', 'https://localhost:3443', 'http://localhost:4200'];
var corsOptionsDelegate = (req, callback) => {
var corsOptions;
console.log(req.header('Origin'));
if(whitelist.indexOf(req.header('Origin')) !== -1) {
corsOptions = { origin: true };
}
else {
corsOptions = { origin: false };
}
callback(null, corsOptions);
};

exports.cors = cors();
exports.corsWithOptions = cors(corsOptionsDelegate);

And also my imageRouter.js:


const express = require('express');
const bodyParser = require('body-parser');

const Images = require('../models/images');
var authenticate = require('../authenticate');

const imagesRouter = express.Router();
const cors = require('./cors');

imagesRouter.use(bodyParser.json());
/*
imagesRouter.options('*', cors.cors, (req, res) => {
     res.sendStatus(200);
     //res.header('Access-Control-Allow-Origin', "*");
     //res.header('Access-Control-Allow-Methods', 'POST');
     //res.header("Access-Control-Allow-Headers", "accept, content-type");
     //res.header("Access-Control-Max-Age", "1728000");
     } );
     */


imagesRouter.route('/')
.options(cors.corsWithOptions, (req, res) => { res.sendStatus(200); })
.get(cors.cors, (req,res,next) => {
    Images.find({})
    .then((images) => {
        res.statusCode = 200;
        res.setHeader('Content-Type', 'application/json');
        res.json(images);

    }, (err) => next(err))
    .catch((err) => next(err));
})

module.exports = imagesRouter;

But I get:

Access to XMLHttpRequest at 'https://localhost:3443/images' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
zone-evergreen.js:2828 GET https://localhost:3443/images net::ERR_FAILED
scheduleTask @ zone-evergreen.js:2828
scheduleTask @ zone-evergreen.js:386
onScheduleTask @ zone-evergreen.js:273
scheduleTask @ zone-evergreen.js:379
scheduleTask @ zone-evergreen.js:211
scheduleMacroTask @ zone-evergreen.js:234
scheduleMacroTaskWithCurrentZone @ zone-evergreen.js:1118
(anonymous) @ zone-evergreen.js:2861
proto.<computed> @ zone-evergreen.js:1433
(anonymous) @ http.js:2615
_trySubscribe @ Observable.js:42
subscribe @ Observable.js:28
call @ tap.js:16
subscribe @ Observable.js:23
subscribeToResult @ subscribeToResult.js:9
_innerSub @ mergeMap.js:59
_tryNext @ mergeMap.js:53
_next @ mergeMap.js:36
next @ Subscriber.js:49
(anonymous) @ subscribeToArray.js:3
_trySubscribe @ Observable.js:42
subscribe @ Observable.js:28
call @ mergeMap.js:21
subscribe @ Observable.js:23
call @ filter.js:13
subscribe @ Observable.js:23
call @ map.js:16
subscribe @ Observable.js:23
call @ catchError.js:16
subscribe @ Observable.js:23
ngOnInit @ header.component.ts:41
callHook @ core.js:3937
callHooks @ core.js:3901
executeInitAndCheckHooks @ core.js:3842
refreshView @ core.js:11795
refreshComponent @ core.js:13217
refreshChildComponents @ core.js:11508
refreshView @ core.js:11829
renderComponentOrTemplate @ core.js:11903
tickRootContext @ core.js:13379
detectChangesInRootView @ core.js:13413
detectChanges @ core.js:15093
tick @ core.js:42683
_loadComponent @ core.js:42733
bootstrap @ core.js:42659
(anonymous) @ core.js:42251
_moduleDoBootstrap @ core.js:42247
(anonymous) @ core.js:42202
invoke @ zone-evergreen.js:365
onInvoke @ core.js:41257
invoke @ zone-evergreen.js:364
run @ zone-evergreen.js:124
(anonymous) @ zone-evergreen.js:851
invokeTask @ zone-evergreen.js:400
onInvokeTask @ core.js:41235
invokeTask @ zone-evergreen.js:399
runTask @ zone-evergreen.js:168
drainMicroTaskQueue @ zone-evergreen.js:570
Promise.then (async)
scheduleMicroTask @ zone-evergreen.js:553
scheduleTask @ zone-evergreen.js:389
scheduleTask @ zone-evergreen.js:211
scheduleMicroTask @ zone-evergreen.js:231
scheduleResolveOrReject @ zone-evergreen.js:841
then @ zone-evergreen.js:967
bootstrapModule @ core.js:42232
./src/main.ts @ main.ts:11
__webpack_require__ @ bootstrap:79
0 @ main.ts:12
__webpack_require__ @ bootstrap:79
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.js:1
Show 28 more frames
home:1 Access to XMLHttpRequest at 'https://localhost:3443/images' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
zone-evergreen.js:2828 GET https://localhost:3443/images net::ERR_FAILED

Standard/recommended way to identify Koa application objects

Middleware like koa-mount has a need to identify Koa application objects, and behave differently if found ( example ).

What would be the standard/recommended way to achieve this? Perhaps by using an exported Symbol in a sub package?

  • const KOA_APPLICATION = require('koa/identification')
    ....
    if ( obj[KOA_APPLICATION] ) ....

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.