Giter Club home page Giter Club logo

oauth-subscriber's Introduction

Guzzle

Guzzle, PHP HTTP client

Latest Version Build Status Total Downloads

Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and trivial to integrate with web services.

  • Simple interface for building query strings, POST requests, streaming large uploads, streaming large downloads, using HTTP cookies, uploading JSON data, etc...
  • Can send both synchronous and asynchronous requests using the same interface.
  • Uses PSR-7 interfaces for requests, responses, and streams. This allows you to utilize other PSR-7 compatible libraries with Guzzle.
  • Supports PSR-18 allowing interoperability between other PSR-18 HTTP Clients.
  • Abstracts away the underlying HTTP transport, allowing you to write environment and transport agnostic code; i.e., no hard dependency on cURL, PHP streams, sockets, or non-blocking event loops.
  • Middleware system allows you to augment and compose client behavior.
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle');

echo $response->getStatusCode(); // 200
echo $response->getHeaderLine('content-type'); // 'application/json; charset=utf8'
echo $response->getBody(); // '{"id": 1420053, "name": "guzzle", ...}'

// Send an asynchronous request.
$request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org');
$promise = $client->sendAsync($request)->then(function ($response) {
    echo 'I completed! ' . $response->getBody();
});

$promise->wait();

Help and docs

We use GitHub issues only to discuss bugs and new features. For support please refer to:

Installing Guzzle

The recommended way to install Guzzle is through Composer.

composer require guzzlehttp/guzzle

Version Guidance

Version Status Packagist Namespace Repo Docs PSR-7 PHP Version
3.x EOL (2016-10-31) guzzle/guzzle Guzzle v3 v3 No >=5.3.3,<7.0
4.x EOL (2016-10-31) guzzlehttp/guzzle GuzzleHttp v4 N/A No >=5.4,<7.0
5.x EOL (2019-10-31) guzzlehttp/guzzle GuzzleHttp v5 v5 No >=5.4,<7.4
6.x EOL (2023-10-31) guzzlehttp/guzzle GuzzleHttp v6 v6 Yes >=5.5,<8.0
7.x Latest guzzlehttp/guzzle GuzzleHttp v7 v7 Yes >=7.2.5,<8.4

Security

If you discover a security vulnerability within this package, please send an email to [email protected]. All security vulnerabilities will be promptly addressed. Please do not disclose security-related issues publicly until a fix has been announced. Please see Security Policy for more information.

License

Guzzle is made available under the MIT License (MIT). Please see License File for more information.

For Enterprise

Available as part of the Tidelift Subscription

The maintainers of Guzzle and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more.

oauth-subscriber's People

Contributors

andreybolonin avatar ashgibson avatar atymic avatar barryvdh avatar casperbakker avatar cerpusoddarne avatar ferdypruis avatar gmponos avatar grahamcampbell avatar jalvarado91 avatar jhoopes avatar jrmadsen67 avatar juampynr avatar mastacheata avatar matthewpeach avatar mtdowling avatar ragboyjr avatar sagikazarmark avatar siwinski avatar thecaliskan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oauth-subscriber's Issues

0.1.1 Release?

Could you tag 0.1.1 please because it allows us to use stable guzzle 4.0.

trailing slash for base_uri

Is trailing slash a must for base_uri? All requests fail with a 404 whenever base_uri doesn't end with a '/'
Not sure if PSR7 specifies base_uri to be so.

Unable to install via Composer

I use oauth-subscriber 0.1.*@dev and Guzzle 5.0 for one of my packages (https://github.com/abhishekbhardwaj/Twitter-API-PHP) and when installing that package on a Laravel project via Composer, it errors out saying "could not be resolved to an installable set of packages".

Adding the following to the Laravel project:

"minimum-stability": "dev",
"prefer-stable": true

..fixes it but then it pulls in unstable versions of other packages as well.

Installing all other dependencies manually into the Laravel project also fixes it but then..

Since this package is working with GuzzleHttp 5.0, how about adding a tag so that Composer can install it without hiccups?

Or any other suggestion would be great as well.

Make release with 'callback' param support added

Please note that switching Composer to use dev-master solves this problem..

When pulling version 0.1.x through Composer, the version being returned is 0.1.1 which does not have the callback param support added.

I propose that version 0.1.2 is released, so that people with 0.1.x required in their projects can get the latest change.

Thanks

How to create OAuth token and OAuth secret

Hi,

I'm trying to use this library but don't really know how to create OAuth token and OAuth secret. Would you please help me?

Thanks

$oauth_consumer_key = '6481-6163-0300';
$consumer_secret = '3qrq46dabjokwsgk4owwk8k4scs00o400kccwc0gs4048k8css';
$oauth_nonce = md5(uniqid(mt_rand(), true));
$oauth_version = "1.0";
$oauth_signature_method = "HMAC-SHA1";
$oauth_token = ???????????????
$oauth_secret = ???????????????

Guzzle 6 support

As Guzzle moved to version 6 there are some major changes that doesn't allow to easily adopt your code. I think quite a lot of people would really appreciate if you produce a solution for v6.

Guzzle 401 response sending data by post

I've been using Guzzle to get data from my API, but when I try and post data to the API I get the following error:

Fatal error: Uncaught exception 'GuzzleHttp\Exception\ClientException' with message 'Client error response [url] http://www.mywebsite.bar/rest/v4/foo/ [status code] 401 [reason phrase] Unauthorized : Invalid signature

The code I'm using to send the data looks like this

$request = $this->client->post('http://www.mywebsite.bar/rest/v4/foo/' ,
  array('Content-Type: application/x-www-form-urlencoded'),
  array());
$request->setBody($my_data); #set body!
$response = $request->send();

return $response;

Using the same client to get data works fine

$res = $this->client->get( $url);
return $res->getBody();

Using OAuth I've managed to post the data to the API like this

$my_data['name'] = 'Bob';
$my_data['age'] = 34;
$my_data['location[home]'] = 'foo';
$my_data['location[work]'] = 'bar';

$oauth->fetch( $url , $my_data , OAUTH_HTTP_METHOD_POST );

Sending the array to the API this way works fine.

I'm using guzzlehttp/oauth-subscriber for all the oauth side.

What am I doing wrong with Guzzle?

Thanks

Incompatible dependency. Use of GuzzleHttp\Psr7\parse_query()

PHP version: 7.3.27

Description
The Oauth1::getSignature() is attempting to leverage GuzzleHttp\Psr7\parse_query(). Howevern the parse_query() was deprecated, and in later versions of GuzzleHttp\Psr7, unavailable. So updating these packages renders this one unusable.
The problem is simply that oauth-subscriber's composer.json isn't restrictive enough. It depends on '"guzzlehttp/guzzle": "^6.0|^7.0"', which in turn depends on '"guzzlehttp/psr7": "^1.7 || ^2.0",'. But guzzlehttp/psr7 v2.0 is what removes that function.

How to reproduce
Any use of the Oauth1::getSignature() method will trigger this.

Possible Solution
Either observe the deprecation notice's instructions and replace these function calls with GuzzleHttp\Psr7\Query::parse(), or just add a more-explicit dependency on guzzlehttp/psr7 that limits it to just '^1.7', and not '^2.0'.

Memory leak

When using oauth-subscriber in cron for multiple times their is a memory leak. Here is a basic test I did.

function oauth_1_stack($token = NULL, $token_secret = NULL)
{
  $stack = HandlerStack::create();

  $middleware = new Oauth1([
    'consumer_key'    => 'my_key',
    'consumer_secret' => 'my_secret',
    'token'           => $token,
    'token_secret'    => $token_secret,
  ]);
  $stack->push($middleware);

  $options = [
    'handler' => $stack,
    'auth' => 'oauth'
  ];

  unset($stack, $middleware);

  return $options;
}

echo "<pre>";
echo memory_get_usage() . "\n"; // 4017480

$options = oauth_1_stack();

echo memory_get_usage() . "\n"; // 4509824

unset($options);

echo memory_get_usage() . "\n"; // 4480032
echo "</pre>";

Notice: Undefined index: token_secret in guzzlehttp/oauth-subscriber/src/Oauth1.php at line 243

I am trying to request_token to twitter with the following code. However this is giving the undefined index here https://github.com/guzzle/oauth-subscriber/blob/master/src/Oauth1.php#L243

    $middleware = new Oauth1([
        'consumer_key'    => 'key',
        'consumer_secret' => 'secret'
    ]);

    $stack->push($middleware);

    $client = new Client([
        'base_uri' => 'https://api.twitter.com/',
        'handler' => $stack,
        'auth' => 'oauth'
    ]);

    $res = $client->post('oauth/request_token', ['form_params' => ['oauth_callback' => 'http://mysite.com/callback']]);

If I change the Oauth1 config to look to include the token_secret and set it to false it works but I don't think this is right.

    $middleware = new Oauth1([
        'consumer_key'    => 'key',
        'consumer_secret' => 'secret',
        'token_secret' => false
    ]);

RSA-SHA1 signing method is not working

Problem is with these lines in GuzzleHttp\Subscriber\Oauth\Oauth1::sign_RSA_SHA1():

$privateKey = openssl_pkey_get_private(
    file_get_contents($this->config['consumer_secret']),
    $this->config['consumer_secret']
);

We have to use $this->config['consumer_secret'] for private key's path, but then $this->config['consumer_secret'] is also used as passphrase and it's not working.

I have two ideas:

  • there should be one additional private_key attribute in constructor's $config so sign_RSA_SHA1() could use $this->config['private_key']. Maybe $this->config['private_key_passphrase'] also? In my opinion it would be most readable.
  • sign_RSA_SHA1() could use $this->config['consumer_key'] for private key's path and $this->config['consumer_secret'] for optional passphrase. But it could be misleading.

Allow override of token and secret on a per-call basis.

At the moment, a single Guzzle client can be set up with this handler, and the operation of the handler can be enabled or disabled by passing the auth parameter to a request send: oauth1 turns it in and null turns it off.

I would like to go one step further, and allow an oauth_token and oauth_token_secret to be passed into the request as options. These should allow the token and secret to be set for that request, and to override the values given to the OAuth1 object when it was created.

Why? It's about making token refreshing more invisible to the application. When a HTTP request is made, it may fail if the token has expired. This can be caught, a fresh token requested, then the HTTP request fired off again. The application should not have to get involved in the logic of this, except for being signalled to persist the new token and secret.

Now, at the moment, to resent the request with new tokens, a new OAuth handler needs to be created. Then a new handler stack. Then a new Guzzle client. This is all done at a very low level where the full configuration used to create all these things may not be known. What's more, the Guzzle client and the OAuth1 handler are immutable, and do not have any with* methods for cloning with a few configuration changes, so we have no workaround.

I'm using this with Xero in the context of a Partner Application. The way OAuth straps itself across every level of API access at he moment, instead of staying nicely in one or two layers, makes for very messy applications. I'm trying to get the OAuth functionality (request and token refreshes) to stay close to where the Guzzle requests are sent.

Is this something that would be acceptable to submit? Useful to anyone else? Am I just missing something - maybe OAuth is neat and easy-peasy, and I'm somehow making it messy and difficult?

Oauth1Test fails on $body::readLine($body)

On my system, $body is a GuzzleHttp\Stream\Stream which does not appear to have any readLine methods.

Fatal error: Call to undefined method GuzzleHttp\Stream\Stream::readLine() in C:\home\ahundiak\zayso2016\oauth\vendor\guzzlehttp\oauth-subscriber\tests\Oauth1Test.php on line 270

guzzlehttp/guzzle 4.2.1
guzzlehttp/oauth-subscriber 0.1.2
guzzlehttp/streams 2.1.0

The rest of the tests work fine.

New release

Please, create new release with latest changes.
Thank you!

Attempted to call function "parse_query" from namespace "GuzzleHttp\Psr7".

PHP version: 7.4.12

Description
Getting an error "Attempted to call function "parse_query" from namespace "GuzzleHttp\Psr7"." In Oauth1.php line 149.
Seems like Guzzle moved functions to another place
Guzzle v7.3.0
oauth-subscriber v0.5.0

How to reproduce
Check functions locations. Functions called from old places

Possible Solution
Update library to be compatible with guzzle v7.3

Additional context

Discrepancy between parameters sent and guzzles PostBody sent

When you add a post parameter with a null value it the entire key value pair is removed from the base signature string, however Guzzle will send the post parameter as an empty parameter. Meaning the server will have a signing mismatch.

One of two things could happen

  1. This plugin should be corrected so null parameters are first coerced into empty strings (probably not what we want?)
  2. Parameters with null values should not be added to the PostBody objects.

Wrong signature for query string with duplicate parameter keys

When sending a request which uses a query containing duplicate parameter keys, the signature is incorrectly generated.

eg. ?parameter=myvalue&paramter=myvalue2

This is being caused by the usage of "http_build_query" instead of the Guzzle "build_query" function in "createBaseString".

Error: Call to undefined function GuzzleHttp\Psr7\parse_query()

PHP version: 7.4.29

Description
I've installed "guzzlehttp/oauth-subscriber": "^0.5" via composer (v2.3.10). I'm using it in Drupal to request an API call.

I've included

use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Subscriber\Oauth\Oauth1;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;

in the code and have used it as

$client = new Client([
        'base_uri' => $this->getBaseUri(),
        'handler' => $this->getAuthHandler(),
        'auth' => 'oauth',
      ]);
$stack = HandlerStack::create();
    $middleware = new Oauth1([
      'realm' => account_id,
      'consumer_key' => consumer_key,
      'consumer_secret' => consumer_secret,
      'token' => token_id,
      'token_secret'=> token_secret,
      'signature_method' => 'HMAC-SHA256',
    ]);
    $stack->push($middleware);

It is basically an import function which fetches data from third party API. When I run the import it gives an error Error: Call to undefined function GuzzleHttp\Psr7\parse_query() in GuzzleHttp\Subscriber\Oauth\Oauth1->getSignature() (line 149 of C:\xampp\htdocs\mystore2\vendor\guzzlehttp\oauth-subscriber\src\Oauth1.php).

I look forward to any suggestions/help. Thanks in advance!

Please tag a recent 0.2.1 release

The move to Guzzle 6 is not going to be simple for some applications and there are fixes that are not included in 0.2.0.

It seems to me like 55c001f5cbcfab5f44792426538cba5bd53168f2 was the last commit before the BC break was made?

OAuth 1.0 Two-Legged

Hello there,
The following is taken from the README file
You can set the auth request option to oauth for all requests sent by the client by extending the array you feed to new Client with auth => oauth.

use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Subscriber\Oauth\Oauth1;

$stack = HandlerStack::create();

$middleware = new Oauth1([
    'consumer_key'    => 'my_key',
    'consumer_secret' => 'my_secret',
    'token'           => 'my_token',
    'token_secret'    => 'my_token_secret'
]);
$stack->push($middleware);

$client = new Client([
    'base_uri' => 'https://api.twitter.com/1.1/',
    'handler' => $stack,
    'auth' => 'oauth'
]);

// Now you don't need to add the auth parameter
$res = $client->get('statuses/home_timeline.json');

Note

You can omit the token and token_secret options to use two-legged OAuth.

It says i can't ommit the token and token secret for two-legged aoth but whe i get rid of those two keys i get thr following exception:

Notice: Undefined index: token_secret in /homepages/42/d560140073/htdocs/oggo/guzzle/vendor/guzzlehttp/oauth-subscriber/src/Oauth1.php on line 243

My question is, does omitting means deleting them or keeping the keys but with an empty value ?

Thank you.

Cant install via composer with guzzle 6

trying to install via composer and ive got the required packages set to
"guzzlehttp/guzzle": "~6.0",
"guzzlehttp/oauth-subscriber": "0.2.*",

But when doing a composer update I get:
Problem 1
- guzzlehttp/oauth-subscriber 0.2.0 requires guzzlehttp/guzzle ~4.0|~5.0 -> satisfiable by guzzlehttp/guzzle[5.3.x-dev].
- guzzlehttp/oauth-subscriber 0.2.0 requires guzzlehttp/guzzle ~4.0|~5.0 -> satisfiable by guzzlehttp/guzzle[5.3.x-dev].
- Conclusion: don't install guzzlehttp/guzzle 5.3.x-dev
- Installation request for guzzlehttp/oauth-subscriber 0.2.* -> satisfiable by guzzlehttp/oauth-subscriber[0.2.0].

Ive tried minimum-stability on dev and stable

Bug in signUsingHmacSha1()

There is a bug in the method signUsingHmacSha1().

To create the $keyit EVER uses both $this->config['consumer_secret']and $this->config['token_secret'].

The problem arises when there is no token_secretset.

In fact, the method works in this way:

/**
 * @param string $baseString
 *
 * @return string
 */
private function signUsingHmacSha1($baseString)
{
    $key = rawurlencode($this->config['consumer_secret'])
        . '&' . rawurlencode($this->config['token_secret']);

    return hash_hmac('sha1', $baseString, $key, true);
}

If a token isn't set the ampersand is anyway added to $keyand this causes the encoding of a wrong string and the generation of a wrong key.

To fix the bug is sufficient an ifstatement, this way:

/**
 * @param string $baseString
 *
 * @return string
 */
private function signUsingHmacSha1($baseString)
{
    $key = rawurlencode($this->config['consumer_secret'])

    // Add token only if present to avoid wrong encoding due to the superflous ampersand (&)
    if(isset($this->config['token_secret']) && !empty($this->config['token_secret'])) {
        $key .= '&' . rawurlencode($this->config['token_secret']);
    }

    return hash_hmac('sha1', $baseString, $key, true);
}

Depricated function was removed

PHP version: 8.1.3
Guzzle version: 7.4.1

Description
Function GuzzleHttp\Psr7\parse_query() used in Oauth1.php was removed and this leads to undefined function error.

How to reproduce
Using oauth-subscriber and Guzzle 7.4.1 run a signed oAuth query.

Possible Solution
Code needs updating to Query::parse() and Query:build().

Guzzel not able to see the nonce and timestamp

was wondering how Guzzel will be able to retrieve the nonce and timestamp when request is fired, usually in 2 legged it should generate automatically but i don't see when i do $request-all() dump from laravel. end point.

post request should include body parameters in base string

I was having some issues using this plugin with the Xero API, trying to POST data. I came across this discussion - https://community.xero.com/developer/discussion/24421/

If you see Tony Rule's comment where he says "When using POST, any form parameters need to be included in the signature base string, whereas PUT method doesn't use them. http://oauth.net/core/1.0a/#anchor13"

I changed my guzzle request to use PUT instead and it worked. I am wondering if this oauth plugin should detect the request type and include any form fields in the base string.

Incorrect signature generated

When passing a request object created via ServerRequest::fromGlobals() an incorrect signature is generated. It seems that the parameter 'oauth_signature' is unset and then re-added after adding the body contents to the params in method getSignature(). Clearing the body fixes the issue.

Code to reproduce the issue:

use GuzzleHttp\Subscriber\Oauth\Oauth1;
use GuzzleHttp\Psr7\ServerRequest;
use function GuzzleHttp\Psr7\stream_for;

$oauth = new Oauth1([
    'consumer_key' => 'key',
    'consumer_secret' => 'secret',
    'token_secret' => ''
]);

$signature = $oauth->getSignature(ServerRequest::fromGlobals(), $_POST);
var_dump($signature === $_POST['oauth_signature']); // false

$signature = $oauth->getSignature(ServerRequest::fromGlobals()->withBody(stream_for()), $_POST);
var_dump($signature === $_POST['oauth_signature']); // true

Possible fix:
Move the line that unsets the 'oauth_signature' parameter after the code that adds the body contents and query parameters:

public function getSignature(RequestInterface $request, array $params)
{
    // Add POST fields if the request uses POST fields and no files
    if ($request->getHeaderLine('Content-Type') == 'application/x-www-form-urlencoded') {
        $body = \GuzzleHttp\Psr7\parse_query($request->getBody()->getContents());
        $params += $body;
    }

    // Parse & add query string parameters as base string parameters
    $query = $request->getUri()->getQuery();
    $params += \GuzzleHttp\Psr7\parse_query($query);

    // Remove oauth_signature if present
    // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
    unset($params['oauth_signature']);

Problem with signatures for query strings without values

What is the correct way to generate the signature for requests with query string that has no key=value just a string without "=" sign for example https://domain/path?querystring

The service im connecting with for urls like that returns invalid signature error.
So who is not compliant with the RFC ? the service or the subscriber implementation ?

With one simple modification to the prepareParameters method i got the requests working, I can make a PR but i dont know it would be a valid change.

private function prepareParameters($data)
{
        // Parameters are sorted by name, using lexicographical byte value
        // ordering. Ref: Spec: 9.1.1 (1).
        uksort($data, 'strcmp');
        foreach ($data as $key => $value) {
            if ($value === null) {
//              unset($data[$key]); // current code
                $data[$key] = ""; // modification needed to make requests with a valid sig
            }
        }
        return $data;
}

PHP8 openssl_free_key deprecated

PHP 8.0.0

Description
Trying to use this in PHP* and the following error is generated when using $client->request();

In Oauth1.php line 267:

Function openssl_free_key() is deprecated

How to reproduce
Use with PHP8

Possible Solution
Remove this reference as PHP automatically frees the memory.

Rest authentication error : Invalid signature - provided signature does not match

$stack = HandlerStack::create();

$middleware = new Oauth1( array(
		'consumer_key' => $user_info['consumer_key'],
		'consumer_secret' => $user_info['consumer_secret'],
		'signature_method' => Oauth1::SIGNATURE_METHOD_HMAC,
		'token' => '', 'token_secret' => ''
	)
);

$stack->push( $middleware );

$client = new Client( array(
		'base_uri' => sprintf( '%s/wp-json/wc/v2/', rtrim( $user_info['site_url'], '/' ) ),
		'handler' => $stack,
		'auth' => 'oauth',
	)
);

$client->post( 'products',
	array(
		'json' => array(
			'name' => $cart_good['goods_name'],
			'type' => 'simple',
			'regular_price' => $cart_good['shop_price'],
			'description' => $cart_good['goods_desc'],
		)
	)
);

Hi there, this library used to work with previous version of woocommerce.
After i update woocommerce to latest version, it completely not working.
I keep getting invalid signature

Wordpress : 4.8
Woocommerce : 3.1.1

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.