Giter Club home page Giter Club logo

go-xmpp's People

Contributors

bitkeks avatar bluemonday avatar crackcomm avatar harald-mueller avatar hoffoo avatar homburg avatar i5heu avatar joyrex2001 avatar kissaki avatar kjx98 avatar lufia avatar marzzzello avatar mattn avatar mdosch avatar mementor avatar mgottschlag avatar milampi avatar papatutuwawa avatar psilva261 avatar qaisjp avatar richp10 avatar ros-tel avatar seletskiy avatar silvolu avatar soygul avatar specode avatar sshikaree avatar sushimako avatar swdunlop avatar thomasbs 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-xmpp's Issues

Disable TLS connection, Return Error: starttls handshake: x509: certificate signed by unknown authority

I set notls=true, but I got error as title when I start the example.go.
The root cause is you set InsecureSkipVerify=false when enable tls, but not set InsecureSkipVerify=true when disable tls. Unfortunately, the InsecureSkipVerify default value is false.
To fix this just add a fragment in example.go:

if !*notls {
		xmpp.DefaultConfig = tls.Config{
			ServerName:         serverName(*server),
			InsecureSkipVerify: false,
		}
	} else {
		xmpp.DefaultConfig = tls.Config{
			ServerName: serverName(*server),
			InsecureSkipVerify:true,
		}
	}

func (c *Client) Close() should wait for closing stream element from the server

I had the problem, that some messages were not delivered when I closed the connection immediately after sending a message. Adding a waiting time of 100 ms between sending and closing solved this.

In the prosody MUC I was told that I should wait for the closing stream element from the server but I think it would be better to have this integrated directly in this lib.

Can't access error replies for IQs

I have a function where I check for the reply to an IQ:

func getIQ(client *xmpp.Client, id string, c chan xmpp.IQ) {
	for {
		msg, err := client.Recv()
		if err != nil {
			log.Fatal(err)
		}

		switch v := msg.(type) {
		case xmpp.IQ:
			if v.ID == id {
				c <- v
				return
			}
		}
	}
}

The problem is that if I get an IQ reply of type='error' it is not accessible but for type='result' it works. Can you please make all IQs accessible?

SCRAM-SHA-1-PLUS + SCRAM-SHA-256-PLUS + SCRAM-SHA-512-PLUS + SCRAM-SHA3-512(-PLUS) supports

Can you add supports of :

  • SCRAM-SHA-1
  • SCRAM-SHA-1-PLUS
  • SCRAM-SHA-224
  • SCRAM-SHA-224-PLUS
  • SCRAM-SHA-256
  • SCRAM-SHA-256-PLUS
  • SCRAM-SHA-384
  • SCRAM-SHA-384-PLUS
  • SCRAM-SHA-512
  • SCRAM-SHA-512-PLUS
  • SCRAM-SHA3-512
  • SCRAM-SHA3-512-PLUS

"When using the SASL SCRAM mechanism, the SCRAM-SHA-256-PLUS variant SHOULD be preferred over the SCRAM-SHA-256 variant, and SHA-256 variants [RFC7677] SHOULD be preferred over SHA-1 variants [RFC5802]".

https://xmpp.org/extensions/inbox/hash-recommendations.html

-PLUS variants:

LDAP:

  • RFC5803: Lightweight Directory Access Protocol (LDAP) Schema for Storing Salted: Challenge Response Authentication Mechanism (SCRAM) Secrets: https://tools.ietf.org/html/rfc5803

HTTP:

2FA:

IANA:

Linked to:

Using channels?

Would it be possible just to create a channel between the server and the client, and the other client as well? Then code would be much cleaner and security would be enhanced, since everything would rely just in the security of the channel.

I do not know if it is able to modify security properties of channels in order to establish some authentication methods and cipherings in the very communications.

Look at this netchan example: https://github.com/qrush/go/blob/master/experiments/netchan/test/main.go

Doesn't handle errors for funky Unicode

Hi! I've recently realized that in 42wim/matterbridge#209 I promised to file a bug upstream (here) but never did. I'm not too sure of the details of what's going on, but it seems that sending fancy Unicode caused this library to generate invalid XMPP stanzas, which then weren't properly error-handled. See the original ticket for details.

/cc @42wim

How to interprete MUC status codes?

When I am using JoinMUCNoHistory to join a MUC the returned status is different from the ones specified here. E.g. after a successful join I got 140 which is not listed there.
Do I have to do some transformation with the status returned from the function?

xmpp.NewClient() is not thread-safe

Calling xmpp.NewClient() from more than one goroutine can cause a data race (exposed by the -race flag for go test)

The culprit is at https://github.com/mattn/go-xmpp/blob/master/xmpp.go#L193, that should create a new config based on the shared DefaultConfig variable instead of modifying DefaultConfig.

This can currently be worked-around by using opts.NewClient() instead (and providing a TLSConfig to opts), but it would be good to fix the race as well.

Change "notls" to the true

Hi,When i edit "example.go" notls key to the 「true」 ,then i run the example.go is return 「starttls handshake: x509: certificate signed by unknown authority」,Can you help me to solve it

Cannot handle XMPP stanza error responses

Following message cannot be parsed:

<message id="3" type="error" to="[email protected]/ABC">
  <gcm xmlns="google:mobile:data">
     {"random": "text"}
  </gcm>
  <error code="400" type="modify">
    <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
      InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n
    </text>
  </error>
</message>

The Other:[] array returns empty:

&{XMLName:{Space:jabber:client Local:message} From: ID: To:[email protected]/ABC Type:error Subject: Body: Thread: Other:[ ]} 

Getting EOF with correct credentials.

Using a node library I can connect to an olark xmpp client.
With golang and the same credentials I get

 (*errors.errorString)(0xc42003c060)(EOF)

The options I'm using are

	opts := xmpp.Options{
		User:     "[email protected]",
		Password: "password",
		NoTLS:    true,
		InsecureAllowUnencryptedAuth: true,
	}

I've also tried without the NoTLS and InsecureAllowUnencryptedAuth options.

wrong idiom if &iq.Bind == nil. It's always not nil.

Bind is struct in struct , so check &iq.Bind == nil is wrong, the sub-struct always have some address

var iq clientIQ
if &iq.Bind == nil {
  log.Printf("&iq.Bind is nil\n")
} else {
  log.Printf("&iq.Bind is not nil\n") // Always printed !
}

Proposed fix:
change in clientIQ definition Bind bindBind to Bind *bindBind, likes:

type clientIQ struct { // info/query
    XMLName xml.Name `xml:"jabber:client iq"`
    From    string   `xml:"from,attr"`
    ID      string   `xml:"id,attr"`
    To      string   `xml:"to,attr"`
    Type    string   `xml:"type,attr"` // error, get, result, set
    Error   *clientError  // Pointer to struct instead nested struct
    Bind    *bindBind    // Pointer...
}

And also change checking if the 'bind' field used to:

if iq.Bind == nil {
  return errors.New("<iq> result missing <bind>")
}

New version memory usage in Win32,
current version unsafe.Sizeof(clientIQ)=136
after my fix unsafe.Sizeof(clientIQ)=56 (in case <iq query...)
So if optional parts are not present, only nil pointer saved.

By the way, in the sruct changed tags:
previous version was xml:",attr", I use xml:"from,attr"

It's important because go xml parser is case sensitive and without the change, did not parse
from, to, type and id

chat.Remote undefined

Hi i can not get the example to work. It is my fist go project so it is probably me
But when i build i get

./example.go:64: chat.Remote undefined (type interface {} has no field or method Remote)
./example.go:64: chat.Text undefined (type interface {} has no field or method Text)

But if i remove the line
fmt.Println(chat.Remote, fromUTF8(chat.Text))
The client goes online and can revive messages, but not display em.

Any ideas?
Thanks

error: PLAIN authentication is not an option

my code is:

package main

import (
    "fmt"
    xmpp "github.com/mattn/go-xmpp"
)

const (
    server   = "talk.google.com:5222"
    username = "myusername"
    password = "mypassword"
)

func main() {
    fmt.Println("hello")
    talk, err := xmpp.NewClientNoTLS(server, username, password, true)
    fmt.Println("error: " + err.Error())
    talk.Send(xmpp.Chat{Remote: "[email protected]", Type: "chat", Text: "hello yangxiao"})
}

and get the result

<stream:stream from="gmail.com" id="0C8386F233123077" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client"><stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"><required/></starttls><mechanisms xmlns="urn:ietf:params:xml:ns:
xmpp-sasl"><mechanism>X-OAUTH2</mechanism><mechanism>X-GOOGLE-TOKEN</mechanism></mechanisms></stream:features>
error: PLAIN authentication is not an option: [X-OAUTH2 X-GOOGLE-TOKEN]
panic: runtime error: invalid memory address or nil pointer dereference

[signal 0xb code=0x1 addr=0x0 pc=0x39764]

goroutine 1 [running]:
github.com/mattn/go-xmpp.(*Client).Send(0x0, 0x253b10, 0x15, 0x231120, 0x4, ...)
        /Users/EnzoYang/src/go_path/src/github.com/mattn/go-xmpp/xmpp.go:398 +0x1b4 
main.main()
        /Users/EnzoYang/Work/Vagrant/pypy/workspace/GO/src/nagi-notify/gtalk.go:19 +0x238

goroutine 2 [syscall]:

my os is mac os x 10.9, my go version is 1.1.2

Unable to build

I cannot build go-xmpp

$ 6g -V
6g version release.r58.1 9046
$ make
6g -o go.6 xmpp.go
xmpp.go:53: undefined: strings.SplitN
xmpp.go:58: undefined: strings.SplitN
xmpp.go:88: undefined: strings.SplitN
xmpp.go:123: undefined: strings.SplitN
make: *** [go.6] Error 1

Empty chat record on Recv

I am using a slightly modified version of your example code (go-iconv doesn't work on my version of Mac OS X but github.com/djimenez/iconv-go does work => my UTF8 conversion functions are slightly different). I can send messages just fine and I can produce some kind of output every time I receive one but the chat record itself is empty. I verified this with

go func() {
    for {
        chat, err := talk.Recv()
        if err != nil {
            log.Fatal(err)
            fmt.Printf("Trouble receiving chat\n")
        }
        fmt.Printf("%v\n", chat)
    }
}()

And I receive { } for each message. Connecting to google talk servers.

reflection fails - Example does not work

Dunno if this issue is because of the update and recent go version, but reflection seems to fail.

panic: reflect.Value.Addr of unaddressable value

runtime.panic+0xac ~/go/src/pkg/runtime/proc.c:1060
runtime.panic(0x4dfe58, 0xf84017c780)
reflect.Value·Addr+0x7e ~/go/src/pkg/reflect/value.go:388
reflect.Value·Addr(0x537110, 0xf8401cf280, 0x0, 0xf8401cf280, 0x0, ...)
github%2ecom/mattn/go-xmpp.next+0x30b ~/go/src/pkg/github.com/mattn/go-xmpp/xmpp.go:425
github%2ecom/mattn/go-xmpp.next(0xf8401c68c0, 0xf84000de00, 0x591e6c, 0x7475613c0000002d)
github%2ecom/mattn/go-xmpp.*Client·init+0x9c4 ~/go/src/pkg/github.com/mattn/go-xmpp/xmpp.go:171
github%2ecom/mattn/go-xmpp.*Client·init(0xf84019e080, 0x7fff35a80b18, 0xf00000008, 0x7fff35a80b3a, 0x8, ...)
github%2ecom/mattn/go-xmpp.NewClient+0x91b ~/go/src/pkg/github.com/mattn/go-xmpp/xmpp.go:107
github%2ecom/mattn/go-xmpp.NewClient(0x575ec4, 0x6b6c617400000013, 0x7fff35a80b18, 0x17, 0x7fff35a80b3a, ...)
main.main+0xbc /home/jan/dev/go/go-xmpp/example.go:27

"auth failure: text"

When I exceed my connection rate with a client, I see the following response stanza being returned by them in debug mode:

<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
  <temporary-auth-failure/>
  <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
    New connection rate exceeded. Try again later.
  </text>
</failure>

However, the error returned by xmpp.NewClient is simply auth failure: text which makes it difficult to detect this error programatically.

Documentation

If this library is intended to be developed by various developers, a better documentation (both comments in the source and external text files) should be developed. Perhaps a raw txt in which a TODO list is proposed and a DESIGN decisions file, just to know why important parts of code are done in the way they are actually done.

XEP-0443: XMPP Compliance Suites 2021

Please add support of XEP-0443: XMPP Compliance Suites 2021: https://xmpp.org/extensions/xep-0443.html

Which replaces:

bind and session use the same id, but id must be unique.

Proposed fix:

func (c *Client) init(o *Options) error {
.....
    if o.Session {
        //if server support session, open it
        cookie = getCookie() // generate new id value for session
        fmt.Fprintf(c.conn, "<iq type='set' id='%x'><session xmlns='%s'/></iq>", cookie, nsSession)
. . .

starttls handshake: x509: certificate has expired or is not yet valid

Not sure if anyone would be able to help here however it appears that the issue might be related to this plugin. I'm trying to configure the https://github.com/skburgart/go-vacbot plugin which appears to use the go-xmpp scripts as it is shown under the vendor files however when it attempts to connect to the Ecovacs XMPP server at msg-na.ecouser.net:5223 it fails with "starttls handshake: x509: certificate has expired or is not yet valid". I have downloaded the repository and updated the vendor files with the latest copy of go-xmpp and rebuilt the plugin as an executable file using https://github.com/MnrGreg/homebridge-ecovacs-deebot however it still fails. I cannot for the life of me figure out how to ignore the TLS for XMPP. I went back to the original plugin the GoLang script is based off of which is https://github.com/wpietri/sucks and an issue at wpietri/sucks#62 makes reference to removing pyasn1 and pyasn1-modules from Python as a workaround but cannot find how to do a similar process for these GoLang scripts.

Existing issues are open under the plugins at skburgart/go-vacbot#3 and at MnrGreg/homebridge-ecovacs-deebot#1.

tls: oversized record received with length 28012

Hi,

We are running a prosody 0.9.12 with TLS enabled. I'm not sure why this error is raised (unknown ciphers maybe?):

2017/02/11 15:04:57 tls: oversized record received with length 28012

I'm not sure how I can debug this SSL/TLS communication.

ServerName not used?

According to [1] ServerName should be used to verify the cert:

// ServerName is used to verify the hostname on the returned
// certificates unless InsecureSkipVerify is given. It is also included
// in the client's handshake to support virtual hosting unless it is
// an IP address.
ServerName string

But when I connect to e.g. the server xmpp.example.org:443 with the user [email protected] and set ServerName like the following example I get this error:

2020/04/05 21:04:35 x509: certificate is valid for example.org, [other domains but not xmpp.example.org] not xmpp.example.org

        var tlsConfig tls.Config    
        tlsConfig.ServerName = strings.Split(user, "@")[1]
        tlsConfig.NextProtos = append(tlsConfig.NextProtos, "xmpp-client") 

        // Set XMPP connection options.    
        options := xmpp.Options{        
                Host:      server,    
                User:      user,    
                [...]
                TLSConfig: &tlsConfig,    
        }   

As I understand the explanation from crypto/tls it should not fail as it should check for example.org and not xmpp.example.org although connecting to xmpp.example.org that's why I suspect the library is ignoring my setting of ServerName.

[1] https://golang.org/pkg/crypto/tls/#Config

local error: record overflow

i edit server is talk.l.gfan.com,that it tell me an local error:

/go-xmpp/example$ go run example.go 
talk.l.gfan.com:5222,[email protected]
2012/04/01 11:30:13 local error: record overflow
exit status 1

but i use talk.google.com:443,got PLAIN error.
2012/04/01 11:28:26 PLAIN authentication is not an option: []
exit status 1

Server waits forever on receiving next(c.p)

https://github.com/mattn/go-xmpp/blob/8a80c8abe319ccc0e61b63684158bffd1a61ca5a/xmpp.go#L315

I placed a few printfs and the server seems to wait on this line forever. No errors thrown either. When I turn debug ON, I was able to see the tag.

boopathi example(master)> go run example.go -server localhost:5222 -username test@boopathi -password testtest -notls -debug
<?xml version='1.0' encoding='UTF-8'?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="boopathi" id="fc88ef3d" xml:lang="en" version="1.0">
SE =  {{http://etherx.jabber.org/streams stream} [{{xmlns stream} http://etherx.jabber.org/streams} {{ xmlns} jabber:client} {{ from} boopathi} {{ id} fc88ef3d} {{http://www.w3.org/XML/1998/namespace lang} en} {{ version} 1.0}]}
<stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"></starttls><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism><mechanism>ANONYMOUS</mechanism><mechanism>CRAM-MD5</mechanism></mechanisms><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><auth xmlns="http://jabber.org/features/iq-auth"/><register xmlns="http://jabber.org/features/iq-register"/></stream:features>
Mechanism =  DIGEST-MD5
<challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">cmVhbG09ImJvb3BhdGhpIixub25jZT0iOXM3dTVMYjByd240VFB6TzBJbUJOMjhXN1dyaHAwT1NzamVtbUFhMyIscW9wPSJhdXRoIixjaGFyc2V0PXV0Zi04LGFsZ29yaXRobT1tZDUtc2Vzcw==</challenge>
<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl">cnNwYXV0aD01MTI1YmIwY2JiNzMxMWMyODlkZmIwMTY3Yzc4Nzc2Yg==</success>
Waiting for next message
</stream:stream>

works without TLS: NoTLS: true, and StartTLS: false

IMHO here bug in switch, should be:

func (c *Client) startTLSIfRequired(f *streamFeatures, o *Options, domain string) (*streamFeatures, error) {

    switch {

    case f.StartTLS == nil:
        // the server does not support STARTTLS
        return f, nil
    case f.StartTLS.Required != nil: // the server requires STARTTLS.
    case o.StartTLS:
        break // the user wants STARTTLS and the server supports it.
    default:
        return f, nil
    }
.......

XEPs and RFCs support page with version

Is OAuth broken?

I've tested the OAuth mechanism but it seems the implementation is broken.

After a while of testing i got it work with the following changes to xmpp.go

                  if m == "X-HIPCHAT-OAUTH2" && o.OAuthToken != ""  {
                        mechanism = m
                        // Oauth authentication: send base64-encoded \x00 token \x00 resource.
                        raw := "\x00" + o.OAuthToken + "\x00" + o.Resource
                        enc := make([]byte, base64.StdEncoding.EncodedLen(len(raw)))
                        base64.StdEncoding.Encode(enc, []byte(raw))
                        outString := fmt.Sprintf("<auth xmlns='http://hipchat.com' node='http://hipchat.com/client/mac' ver='22' mechanism='oauth2'>%s</auth>", enc)
                        fmt.Println(outString)
                        fmt.Fprint(c.conn, outString)
                        break
                  }
                  if m == "PLAIN" && o.Password != "" {
                        mechanism = m
                        // Plain authentication: send base64-encoded \x00 user \x00 password.
                        raw := "\x00" + user + "\x00" + o.Password
                        enc := make([]byte, base64.StdEncoding.EncodedLen(len(raw)))
                        base64.StdEncoding.Encode(enc, []byte(raw))
                        fmt.Fprintf(c.conn, "<auth xmlns='%s' mechanism='PLAIN'>%s</auth>\n", nsSASL, enc)
                        break
                  }

now i'm receiving the following output

<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl' jid='<jid_number>@chat.btf.hipchat.com/bot||proxy|<myHost>|<number>' api_host='<myHost>' chat_host='chat.btf.hipchat.com' muc_host='conf.btf.hipchat.com' web_host='<myHost>'/>

but the client throws still an error

another implementation of the oauth could be found here
daneharrigan/hipchat@74f6164

is anyone using oauth in xmpp?

server ping not replied

receiving ping from openfire 4.0.1 with double quote mark but current code check only single quotes

		case *clientIQ:
			if bytes.Equal(v.Query, []byte(`<ping xmlns='urn:xmpp:ping'/>`)) || bytes.Equal(v.Query, []byte(`<ping xmlns="urn:xmpp:ping"/>`)) {

Broken URL in oob message.

When sending a file via http-upload you usually send the URL in oob and in the message body. But it seems the Ooburl is getting altered (compare oob URL to URL in body):

<body>https://upload.example.org:5281/upload/PBOIXpKDzGecqJzo/&amp;%25%3c%3e.txt</body><x xmlns='jabber:x:oob'><url>https://upload.example.org:5281/upload/PBOIXpKDzGecqJzo/&amp;%3c%!e(MISSING).txt</url></x>

User Avatar Implementation

In order to allow matterbridge to spoof the avatar of XMPP users in other chat services, I decided to implement a bit of XEP-0084 (User Avatar) by giving go-xmpp the ability to subscribe to pubsub nodes and request their data.

I have a working implementation which currently contains both my patchsets - PubSub and User Avatar. I will try to get them separated so that I can create two smaller PRs, unless desired otherwise.

is this project FCM-ready?

hello! and thank you for this useful repo. I'd like to know whether it would be possible to use this repo to create an XMPP connection with Google's FCM servers.

Unlike the (soon to be obsolete) GCM servers, the FCM servers require some authentication (see: https://firebase.google.com/docs/cloud-messaging/auth-server):

The connection has two important requirements:

You must initiate a Transport Layer Security (TLS) connection. Note that FCM doesn't currently support the STARTTLS extension.
FCM requires a SASL PLAIN authentication mechanism using <your_FCM_Sender_Id>@gcm.googleapis.com (FCM sender ID) and the Server key as the password. These values are available in the Cloud Messaging tab of the Firebase console Settings pane.

and of course, this connection would open over their ports (5235/5236).

is this repo FCM-ready? if not, roughly what are the required changes?

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.