ethanent / phin Goto Github PK
View Code? Open in Web Editor NEWNode HTTP client
License: MIT License
Node HTTP client
License: MIT License
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
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
}
}
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
Is setting local address possible with this library?
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)
Hello, I was going to open a PR for both phin and centra and add a few improvements:
forEach
with for-loop
for performance reasonselse
const
over let
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?
if JSON.parse fails it should return {}
maybe you can do someting like
try {
return JSON.parse(data);
}
catch (error) {
return {};
}
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:
sendAs
to 'raw'
, which would become a breaking change (since currently 'json'
is assumedoptions.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
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.
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
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?
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.
Transparent support for http2 would be nice!
Anyone having issues with the NPM release 2.6.0? If possible, fix the tests
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>>
Hi,
I am trying to make a request with multipart/form-data. Is it possible to send such requests in phin.
Can I use form-data in phin??
On line 27,28 2 errors:
TS2304: Cannot find name 'IWithData'.
TS2304: Cannot find name 'IWithForm'.
Fixed with changing IWithData to phin.IWithData and IWithForm to phin.IWithForm
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
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
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.
I believe URL
is not defined as a global unless you are using dom types. microsoft/TypeScript#10792
As a workaround, adding a d.ts
file with the following solves it for now.
declare type URL = import('url').URL;
Use promises!
A potential security vulnerability has been disclosed for this repo https://huntr.dev/bounties/01d7ff2a-a699-44a8-8add-77c9eebaec87/ 3 months ago .
But i see it still not addressed .
Kindly validate the bug
How can we pass basic auth credentials as part of the request url?
Example:
https://admin:[email protected]/basic_auth
const p = require('phin');
await p({
url: 'https://admin:[email protected]/basic_auth',
method: 'GET'
})
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?
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
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.
http://localhost/
where the root page is compressed with brotli, that is, the file to access is index.html.br
http://localhost/index.html.br
index.html
contentAdd 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
?
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!
This is how i usually import and use it
import * as p from 'phin`
...
const res = await p({url: "Some url", method: "POST", data:{...form} })
I hope to has this feature because Create-React-App cannot minify ES6 code, you can read more about it here.
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 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.
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)
You should use application/x-www-form-urlencoded
instead of application/x-www-url-form-encoded
in POST requests. See RFC 1867.
In the name of small-package-size the tests folder can be omitted from publication in the .npmignore file
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?
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"
.
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".
Hello! My TypeScript complains on the very first example you provide in the readme:
I guess this type declaration has to be either Object
(it has toString
already) or { [key: string]: any, toString(): string }
.
What do you think? I will be happy to make a PR.
Thanks for great work.
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.
Hi π
I think there's a problem with either the response body parsing or the type definitions.
Looking at type definitions, the response body is of type string
when we're using parser: 'none'
.
The body is in fact the Buffer
object initialized in centra.
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.
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
Received error:
TypeError [ERR_INVALID_ARG_TYPE]: The "msecs" argument must be of type number. Received type object
It seems that node add several changes to handle socket timeout and agent here nodejs/node@949e885#diff-5f7fb0850412c6be189faeddea6c5359R180. This impacts phin
as the default value for timeout
is null
sending request with timeout:
added fix the issue
Error: Cannot find module 'phin' However I've installed it??
It just doesn't make sense....
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.