Git Product home page Git Product logo

phin's Issues

Add JSON Post/Put support

Add support for posting/putting JSON.

Would be cool if we could just do this:

p({url: "some url", method: "POST", json: {foo: 'bar'});

Which would set the Content-Type and Accepts headers to application/json

ReferenceError: Buffer is not defined

I think it would be helpful for people who decided to use it on frontend or something else that includes browser...
It happens if you use webpack5+

The solution is that you need to add these lines to your webpack config

module.exports = {
  ...
  node: {
    process: true,
    Buffer: true
  }
}

HTTP proxy support

Hi,

another missing feature I noticed missing, compared to require, is the support for HTTP proxy. The best would be to auto detect it based on environment variables and/or also as an option when calling phin.

What do you think? Are you interested in implementing it?

Best regards,
Julian

Potential security issue

Hey there!

I belong to an open source security research community, and a member (@ranjit-git) has found an issue, but doesn’t know the best way to disclose it.

If not a hassle, might you kindly add a SECURITY.md file with an email, or another contact method? GitHub recommends this best practice to ensure security issues are responsibly disclosed, and it would serve as a simple instruction for security researchers in the future.

Thank you for your consideration, and I look forward to hearing from you!

(cc @huntr-helper)

Contribution Guide

Hello, I was going to open a PR for both phin and centra and add a few improvements:

  • Replace forEach with for-loop for performance reasons
  • Remove unnecessary else
  • Use of const over let
  • Migrate to use TypeScript

Is there a contribution guide or should I just open a PR and put it up for review? Also, I've noticed the codebase does not use any linter. Any interest in adding one?

try parse JSON and catch error

if JSON.parse fails it should return {}

maybe you can do someting like

    try {
      return JSON.parse(data);
    }
    catch (error) {
      return {};
    }

not possible to pass data as buffer

it seems that when passing a Buffer in const options = { data: Buffer.from('foo') }, centra would handle it as json since typeof Buffer resolves to object.
I see two solutions here:

  1. default sendAs to 'raw', which would become a breaking change (since currently 'json' is assumed
  2. add options.buffer and leave options.data as is. When options.buffer is used, call req.body(options.buffer, 'raw')

Thoughts? Happy to provide PR after discussion about suggested options

ReferenceError: Buffer is not defined

ReferenceError: Buffer is not defined
    at eval (util.js?9eb9:103)
    at Object.../node_modules/core-util-is/lib/util.js (route-discover.chunk.125f9.js:126)
    at __webpack_require__ (bundle.js:833)
    at fn (bundle.js:130)
    at Object.eval (_stream_readable.js?0740:67)
    at eval (_stream_readable.js:1040)
    at Object.../node_modules/readable-stream/lib/_stream_readable.js (route-discover.chunk.125f9.js:460)
    at __webpack_require__ (bundle.js:833)
    at fn (bundle.js:130)

Please help me. I do need your help a lot.
The problem is that global variable Buffer is defined in nodejs but not in browser, so we need to have polyfill.

Follow redirects

Hi,

I'm using this library at the moment which is very cool as it is small, lightweight and it does its job pretty well. Although I currently miss one small feature that is the ability to follow redirects if a specific URL replies back with any Location header inside of it.

Would you mind implementing it in your own library?

Thank you in advance,
Julian

Support query string parameters

I'm probably dense, but how do you nicely add query string parameters, e.g. to a GET request? Looking at centra there's a .query function on the request object but I don't see that supported in phin. It seems it would be easy to add that?

Aborted connection causes request to hang forever

I'm trying to use phin for testing edge cases during the HTTP server shutdown and discovered that a request made with phin will hang forever if it's aborted before the transfer is complete. Here's a minimal reproducible code snippet showing this behaviour:

"use strict";
const phin = require("phin");
const http = require("http");
const util = require("util");

async function test() {
    let server = http.createServer();
    await util.promisify(server.listen.bind(server))();
    server.on("request", (req, res) => {
        // write some data, then abort the connection
        res.write("partial", () => {
            res.socket.destroy();
        });
    });

    // hangs forever
    await phin(`http://localhost:${server.address().port}/`);

    console.log("never reached");
}

test().catch(console.log);

It appears that this is not properly handled in CentraRequest.js: there's handlers added for error and end events of the incommingMessage stream, but an aborted connections does not raise either of these. There's a separate aborted event for this situation.

Types for "defaults" function

There is a disclaimer in the types file:

// Default Options feature is not supported because it's basically impossible to write strongly-typed definitions for it.

I think perhaps Partial<T> is the piece of the puzzle you were missing? I tried to write a definition, but I'm not sure I understand the relation between JS source & TS types. Does this help? (might not be correct!)

export function defaults<T>(
  defaultOptions:
    | Partial<phin.IJSONResponseOptions>
    | Partial<IWithData<phin.IJSONResponseOptions>>
    | Partial<IWithForm<phin.IJSONResponseOptions>>
): (
  options:
    | phin.IJSONResponseOptions
    | IWithData<phin.IJSONResponseOptions>
    | IWithForm<phin.IJSONResponseOptions>
) => Promise<phin.IJSONResponse<T>>

How can we send file with phin?

Hi,

I'm trying sending a file with phin but without results. I tried in data of in form, nothing works.
Is there a way to send a file with phin? If yes, how can we do it?

Thanks,

Maxime

Type for options for POST request not exported

The type used for POST requests is IWithData<phin.IOptions> but the IWithData is not exported in types.d.ts so there's no way to construct a typed options object without making a custom type.

Also, there's a note in the types about using the generics to make JSON/Form posting mutually exclusive, but wouldn't this work just as well?

export interface IOptions extends IOptionsBase {
 parse?: 'none'
}

interface WithData {
  data: object;
}

interface WithForm {
  form: {
    [index: string]: string;
  }
}

export type IOptionsWithData = IOptions & WithData;
export type IOptionsWithForm = IOptions & WithForm;
// etc

Not suitable for browser use

Despite being ultra-lightweight for server side use, this does not extend to the browser. Using Webpack, phin compiles to ~148KB (compare that to ~14.6KB for axios). At the least, I think that there should be a disclaimer about this . At the most, it would be great if a browser-ready version of phin was made.

TypeError: URL is not a constructor

I'm trying to make a simple post request but i'm getting the error
TypeError: URL is not a constructor at new CentraRequest (CentraRequest.js?0a95:14) at module.exports (createRequest.js?ca09:4) at phin (phin.min.js?e014:1) at _callee$ (VM1328 index.vue:333) at tryCatch (runtime.js?96cf:45) at Generator.invoke [as _invoke] (runtime.js?96cf:274) at Generator.prototype.<computed> [as next] (runtime.js?96cf:97) at asyncGeneratorStep (asyncToGenerator.js?1da1:3) at _next (asyncToGenerator.js?1da1:25) at eval (asyncToGenerator.js?1da1:32)
Here's my code:
await p({ url: "example.com", method: "POST", data: { test: 'hello' } });
Does anybody know how to fix this?

phin centra Cannot find module "."

In my project used phin, when I view my page the browse's console display error log like this:
Uncaught Error: Cannot find module "."
at createRequest.js:3
at Object.+1SP (createRequest.js:3)
at t (bootstrap 0aea77b2c74adfcd1d30:54)
at Object.jBJh (phin.min.js:6)
at t (bootstrap 0aea77b2c74adfcd1d30:54)
at Object.QBjc (example.svg:10)
at t (bootstrap 0aea77b2c74adfcd1d30:54)
at Object./AcQ (language.svg:10)
at t (bootstrap 0aea77b2c74adfcd1d30:54)
at Object.2NXm (UcarHeadline.vue:27)

Here are building logs:
$ npm run build test
Hash: 0aea77b2c74adfcd1d30
Version: webpack 3.12.0
Time: 31284ms

WARNING in ./node_modules/centra/createRequest.js
3:22-80 Critical dependency: the request of a dependency is an expression
@ ./node_modules/centra/createRequest.js
@ ./node_modules/phin/lib/phin.min.js
@ ./src/service/apinew.js
@ ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/pages/index.vue
@ ./src/pages/index.vue
@ ./src/router/index.js
@ ./src/main.js

Here are version info:
$ npm ls centra
-- [email protected]
-- [email protected]

Thks

Support for brotli compression

The package is used inside Pactum and do not access brotli compressed files.

I know it is an indirect issue (the culprit is phin or pactum?), but I'm trying to collect more evidence on the problem.

Environment details

  • Programming language: Javascript
  • OS: Windows 11
  • Language runtime version: Node 18.11.0
  • Package version: 3.6.0

Steps to reproduce

  1. Access http://localhost/ where the root page is compressed with brotli, that is, the file to access is index.html.br
  2. The server respond with 404
  3. Now access http://localhost/index.html.br
  4. The server find the file but return the compressed binary content.
  5. Use an external brotli decompressor and the returned data is indeed the index.html content

Redirect limit

Add a redirect limit by default when the user enables followRedirects, and allow followRedirects to be set to a number signifying the max number of redirects to follow.

What would be a sensible number to cap at for followRedirects: true?

How to use http-auth?

Hello!

I looked through documentation & source code, but neither mentions how to provide authorization parameters.

For example, in axios, there is a configuration parameter auth used to pass the username, password to perform a request to protected service.

How do I pass these parameters in phin?

Thanks!

Support for ES5

I hope to has this feature because Create-React-App cannot minify ES6 code, you can read more about it here.

Deprecated usage of node _headers

Describe the bug

According to Node.js Deprecated APIs, OutgoingMessage.prototype._headers in v12 has been deprecated and on the other hand i see some deprecation logs while using Axios.

(node:89822) [DEP0066] DeprecationWarning: OutgoingMessage.prototype._headers is deprecated

To Reproduce
Calling an endpoint in Node.js v12

Environment:

Phin Version: 3.4.1
OS: OSX 10.15

Related Links

https://stackoverflow.com/questions/56697360/how-to-fix-node12388-dep0066-deprecationwarning-outgoingmessage-prototype
https://nodejs.org/api/deprecations.html#deprecations_dep0066_outgoingmessage_prototype_headers_outgoingmessage_prototype_headernames
http-party/http-server#537

Type definitions not bundled with the release (3.4.0)

Type definitions for TypeScript seems to not be bundled with the 3.4.0 release on npm.

Encountered this issue by installing [email protected] in a TypeScript (v3.6.4) project and receiving the error:

Could not find a declaration file for module 'phin'. '/node_modules/phin/lib/phin.min.js' implicitly has an 'any' type.
  Try `npm install @types/phin` if it exists or add a new declaration (.d.ts) file containing `declare module 'phin';`

The thing is, the @types/phin package is just a stub since it's expected that phin provides it's own type definitions. But when I inspect node_modules/phin it indeed seems like there is no types.d.ts file.

Exception when requesting a compressed stream

It appears, when stream: true and compression: true, centra delivers a gzip stream which does no contain a headers
property, causing an exception in phin.js at res.headers.hasOwnProperty('location')

const phin = require("phin");

phin({
	url: "https://github.com/",
	stream: true,
	compression: true,
}).then(function(resp){
	console.log(resp);
}).catch(function(err){
	console.log(err.stack);
});
TypeError: Cannot read properties of undefined (reading 'hasOwnProperty')
    at phin (.../node_modules/phin/lib/phin.js:60:18)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

POST form

You should use application/x-www-form-urlencoded instead of application/x-www-url-form-encoded in POST requests. See RFC 1867.

Built-in cookie support

Really awesome tool- have started using it in a lot of my projects, so thanks for all the time and effort you've put into it 😊

I've done a brief search of the repo, and there doesn't seem to be any mention of cookies. Do you have any plans for cookie management?

Options persisting between successive calls when using phin.defaults()

When using an instance created from phin.defaults(), any options passed will persist between successive calls.

For example:

const phinInstance = phin.defaults({
    url: "https://httpbin.org/get"
});

await phinInstance({
    method: "GET",
    headers: {
        foo: "bar"
    }
});

await phinInstance({
    method: "GET"
});

Expected result: the first HTTP request should be sent with header "foo": "bar", and the second one should not.

Actual result: both HTTP requests are sent with header "foo": "bar".

Documentation link not working as expected.

On this page: https://ethanent.github.io/phin/

The first link for "Full documentation" is a link to the same page. Having a link with the text "Full documentation" implies that the link has more documentation than is offered on the current page, and can be confusing to the person attempting to read more documentation on phin. Same applies for the section "Full Documentation".

Don't parse JSON if response is a server error

Related to #48

When a server responds with a status code of 5xx, the body should not be parsed as JSON.

import * as p from 'phin';

const makeRequest() {
  const url = 'https://google.com';

  const opts: p.IJSONResponseOptions = {
    url,
    method: 'GET',
    parse: 'json',
    headers: {
      accept: 'application/json',
    },
  };

  const result = await p(opts);

  return result.body;

If the server returns a 500 Internal Server Error, the JSON parse still happens and the error is Unexpected token I in JSON at position 0. It appears the only way around this is to not have phin parse the JSON and to do it manually after checking the statusCode.

I think it makes more sense for phin to not parse the JSON unless the statusCode is a 2xx.

Wrong type on response body

Hi πŸ‘‹

I think there's a problem with either the response body parsing or the type definitions.

Expected

Looking at type definitions, the response body is of type string when we're using parser: 'none'.

Experienced

The body is in fact the Buffer object initialized in centra.

Resolution

I think those type definitions have to be fixed or the buffer has to be consumed to produce a string instead.

I'll be happy to help with a PR once I got your opinion on that.

Unexpected end of JSON input on 204 response

Hi there,

I seem to be getting an error from the phin library when an API returns a 204 status code which indicates that the response has no content. This looks like it is due to the parse: "json" option which tries to parse null instead of ignoring it. I will take a look at the source and see if it's an easy fix but just raising this issue for visibility

Errors

Error: Cannot find module 'phin' However I've installed it??
It just doesn't make sense....

  • [email protected]
    updated 1 package and audited 1021 packages in 1.734s
    found 0 vulnerabilities

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.