From 97d27375c673fb5f3c8986aac09f0b41e4f1d0cd Mon Sep 17 00:00:00 2001 From: Gabriel Csapo Date: Fri, 10 Nov 2017 10:39:51 -0800 Subject: [PATCH 01/14] updates docs (#26) * updates docs - adds extensive docs to Git, Util and Service - adds named function to events to trace errors more easily * fixes req to be typed http.IncomingMessage --- CHANGELOG.md | 5 + docs/code/Git.html | 2357 +++++++++++++++++++++++- docs/code/HttpDuplex.html | 100 +- docs/code/Service.html | 385 +++- docs/code/git.js.html | 230 +-- docs/code/global.html | 954 ---------- docs/code/http-duplex.js.html | 104 +- docs/code/index.html | 2 +- docs/code/module-lib_util.html | 453 ++++- docs/code/service.js.html | 77 +- docs/code/util.js.html | 75 +- lib/git.js | 228 +-- lib/http-duplex.js | 102 +- lib/service.js | 75 +- lib/util.js | 73 +- test/{httpduplex.js => http-duplex.js} | 18 +- 16 files changed, 3666 insertions(+), 1572 deletions(-) delete mode 100644 docs/code/global.html rename test/{httpduplex.js => http-duplex.js} (93%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 060b988..d3ef6d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# Unreleased + +- adds extensive docs to Git, Util and Service +- adds named function to events to trace errors more easily + # 0.3.3 (11/05/2017) - Removes dependency on http-duplex package replacing w/ internal replacement lib diff --git a/docs/code/Git.html b/docs/code/Git.html index b13e5a0..68653ba 100644 --- a/docs/code/Git.html +++ b/docs/code/Git.html @@ -22,7 +22,7 @@
@@ -53,7 +53,7 @@

-

new Git(repoDir, options) → {Git}

+

new Git(repoDir, options)

@@ -65,7 +65,7 @@

new GitSource:
@@ -105,49 +105,7 @@

new Git -

events

repos.on('push', function (push) { ... }

Emitted when somebody does a git push to the repo.

-

Exactly one listener must call push.accept() or push.reject(). If there are - no listeners, push.accept() is called automatically.

-

push is an http duplex object (see below) with these extra properties: -push.repo -push.commit -push.branch

-

repos.on('tag', function (tag) { ... }

Emitted when somebody does a git push --tags to the repo.

-

Exactly one listener must call tag.accept() or tag.reject(). If there are - no listeners, tag.accept() is called automatically.

-

tag is an http duplex object (see below) with these extra properties: -tag.repo -tag.commit -tag.version

-

repos.on('fetch', function (fetch) { ... }

Emitted when somebody does a git fetch to the repo (which happens whenever you - do a git pull or a git clone).

-

Exactly one listener must call fetch.accept() or fetch.reject(). If there are - no listeners, fetch.accept() is called automatically.

-

fetch is an http duplex objects (see below) with these extra properties: -fetch.repo -fetch.commit

-

repos.on('info', function (info) { ... }

Emitted when the repo is queried for info before doing other commands.

-

Exactly one listener must call info.accept() or info.reject(). If there are - no listeners, info.accept() is called automatically.

-

info is an http duplex object (see below) with these extra properties: -info.repo

-

repos.on('head', function (head) { ... }

Emitted when the repo is queried for HEAD before doing other commands.

-

Exactly one listener must call head.accept() or head.reject(). If there are - no listeners, head.accept() is called automatically.

-

head is an http duplex object (see below) with these extra properties: -head.repo

-

push.on('response', function(response, done) { ... })

Emitted when node-git-server creates a response stream that will be sent to the git client on the other end.

-

This should really only be used if you want to send verbose or error messages to the remote git client.

-

response is a writable stream that can accept buffers containing git packfile sidechannel transfer protocol encoded strings. done is a callback that must be called when you want to end the response.

-

If you create a response listener then you must either call the done function or execute the following end sequence when you want to end the response:

-
   response.queue(new Buffer('0000'))
-   response.queue(null)

If you never use the response event then the above data will be sent by default. Binding a listener to the response event will prevent the end sequence those from being sent, so you must send them yourself after sending any other messages.

-

http duplex objects

The arguments to each of the events 'push', 'fetch', 'info', and 'head' are http duplex that act as both http - server request and http server response objects so you can pipe to and from them.

-

For every event if there are no listeners dup.accept() will be called - automatically.

-

dup.accept()

Accept the pending request.

-

dup.reject()

Reject the pending request.

+

Handles invoking the git-*-pack binaries

@@ -360,8 +318,7 @@
Properties
-

If opts.checkout is true, create and expected checked-out repos instead of - bare repos

+

If opts.checkout is true, create and expected checked-out repos instead of bare repos

@@ -388,38 +345,57 @@
Properties
-
Returns:
- + + + + +

Extends

-
-
- Type -
-
-Git -
-
+ + + - + + +

Methods

- + + + + + +

(static) close()

+ + + + + + +
+
Source:
+
+ @@ -428,35 +404,68 @@
Returns:
- - + + + + + + + -
+ -
-

- Git -

- + -
-
-
+
+ + + + + +
+

closes the server instance

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + -

new Git()

+

(static) create(repo, callbackopt)

@@ -468,7 +477,7 @@

new GitSource:
@@ -507,6 +516,12 @@

new Git +

Create a new bare repository repoName in the instance repository directory.

+ + + + @@ -515,32 +530,138 @@

new GitParameters:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
repo + + +String + + + + + +

the name of the repo

callback + + +function + + + + + + <optional>
+ + + + + +

Optionally get a callback cb(err) to be notified when the repository was created.

+ + + + + + + + + + + + + + + + + + + +

(static) exists(repo, callbackopt)

+ + + + + + +
+
Source:
+
+ - + + + @@ -551,6 +672,2092 @@

new Git + + + + + +
+

Find out whether repoName exists in the callback cb(exists).

+
+ + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
repo + + +String + + + + + + + + + +

name of the repo

callback + + +function + + + + + + <optional>
+ + + + + +

function to be called when finished

+ + + + + + + + + + + + + + + + + + + + + +

(static) handle(req, res)

+ + + + + + +
+ + +
Source:
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

Handle incoming HTTP requests with a connect-style middleware

+
+ + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
req + + +Object + + + +

http request object

res + + +Object + + + +

http response object

+ + + + + + + + + + + + + + + + + + + + + +

(static) list(callback)

+ + + + + + +
+ + +
Source:
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

Get a list of all the repositories

+
+ + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
callback + + +function + + + +

function to be called when repositories have been found function(error, repos)

+ + + + + + + + + + + + + + + + + + + + + +

(static) listen(port, callback)

+ + + + + + +
+ + +
Source:
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

starts a git server on the given port

+
+ + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
port + + +Number + + + +

the port to start the server on

callback + + +function + + + +

the function to call when server is started or error has occured

+ + + + + + + + + + + + + + + + + + + + + +

(static) mkdir(dir, callbackopt)

+ + + + + + +
+ + +
Source:
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

Create a subdirectory dir in the repo dir with a callback cb(err).

+
+ + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
dir + + +String + + + + + + + + + +

directory name

callback + + +function + + + + + + <optional>
+ + + + + +

callback to be called when finished

+ + + + + + + + + + + + + + + + + + + + + + +

Events

+ + + + + + +

fetch

+ + + + + + +
+ + +
Source:
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
fetch + + +HttpDuplex + + + +

an http duplex object (see below) with these extra properties:

+
Properties
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
repo + + +String + + + +

the string that defines the repo

commit + + +String + + + +

the string that defines the commit sha

+ +
+ + + + + + + + + + +
Type:
+
    +
  • + +Object + + +
  • +
+ + + + + +
Example
+ +
repos.on('fetch', function (fetch) { ... }
+
+    Emitted when somebody does a `git fetch` to the repo (which happens whenever you
+    do a `git pull` or a `git clone`).
+
+    Exactly one listener must call `fetch.accept()` or `fetch.reject()`. If there are
+    no listeners, `fetch.accept()` is called automatically.
+ + + + + + + + + + + + + + + + + + + + + + + +

head

+ + + + + + +
+ + +
Source:
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
head + + +HttpDuplex + + + +

an http duplex object (see below) with these extra properties:

+
Properties
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
repo + + +String + + + +

the string that defines the repo

+ +
+ + + + + + + + + + +
Type:
+
    +
  • + +Object + + +
  • +
+ + + + + +
Example
+ +
repos.on('head', function (head) { ... }
+
+    Emitted when the repo is queried for HEAD before doing other commands.
+
+    Exactly one listener must call `head.accept()` or `head.reject()`. If there are
+    no listeners, `head.accept()` is called automatically.
+ + + + + + + + + + + + + + + + + + + + + + + +

info

+ + + + + + +
+ + +
Source:
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
info + + +HttpDuplex + + + +

an http duplex object (see below) with these extra properties:

+
Properties
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
repo + + +String + + + +

the string that defines the repo

+ +
+ + + + + + + + + + +
Type:
+
    +
  • + +Object + + +
  • +
+ + + + + +
Example
+ +
repos.on('info', function (info) { ... }
+
+    Emitted when the repo is queried for info before doing other commands.
+
+    Exactly one listener must call `info.accept()` or `info.reject()`. If there are
+    no listeners, `info.accept()` is called automatically.
+ + + + + + + + + + + + + + + + + + + + + + + +

info

+ + + + + + +
+ + +
Source:
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
info + + +HttpDuplex + + + +

an http duplex object (see below) with these extra properties:

+
Properties
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
repo + + +String + + + +

the string that defines the repo

+ +
+ + + + + + + + + + +
Type:
+
    +
  • + +Object + + +
  • +
+ + + + + +
Example
+ +
repos.on('info', function (info) { ... }
+
+    Emitted when the repo is queried for info before doing other commands.
+
+    Exactly one listener must call `info.accept()` or `info.reject()`. If there are
+    no listeners, `info.accept()` is called automatically.
+ + + + + + + + + + + + + + + + + + + + + + + +

push

+ + + + + + +
+ + +
Source:
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
push + + +HttpDuplex + + + +

is a http duplex object (see below) with these extra properties

+
Properties
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
repo + + +String + + + +

the string that defines the repo

commit + + +String + + + +

the string that defines the commit sha

branch + + +String + + + +

the string that defines the branch

+ +
+ + + + + + + + + + +
Type:
+
    +
  • + +Object + + +
  • +
+ + + + + +
Example
+ +
repos.on('push', function (push) { ... }
+
+    Emitted when somebody does a `git push` to the repo.
+
+    Exactly one listener must call `push.accept()` or `push.reject()`. If there are
+    no listeners, `push.accept()` is called automatically.
+ + + + + + + + + + + + + + + + + + + + + + + +

tag

+ + + + + + +
+ + +
Source:
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
tag + + +HttpDuplex + + + +

an http duplex object (see below) with these extra properties:

+
Properties
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
repo + + +String + + + +

the string that defines the repo

commit + + +String + + + +

the string that defines the commit sha

version + + +String + + + +

the string that defines the repo

+ +
+ + + + + + + + + + +
Type:
+
    +
  • + +Object + + +
  • +
+ + + + + +
Example
+ +
repos.on('tag', function (tag) { ... }
+
+    Emitted when somebody does a `git push --tags` to the repo.
+    Exactly one listener must call `tag.accept()` or `tag.reject()`. If there are
+    No listeners, `tag.accept()` is called automatically.
+ + + + + + + + + + + + + + + + + + + + diff --git a/docs/code/HttpDuplex.html b/docs/code/HttpDuplex.html index 76c7f6f..3bc0df1 100644 --- a/docs/code/HttpDuplex.html +++ b/docs/code/HttpDuplex.html @@ -22,7 +22,7 @@
@@ -266,7 +266,7 @@

Members

-

(readonly) headers :object

+

(readonly) headers :Object

@@ -333,7 +333,7 @@
Type:
  • -object +Object
  • @@ -426,7 +426,7 @@
    Type:
    -

    (readonly) method :string

    +

    (readonly) method :String

    @@ -495,7 +495,7 @@
    Type:
    • -string +String
    • @@ -513,7 +513,7 @@
      Example
      -

      (readonly) readable :boolean

      +

      (readonly) readable :Boolean

      @@ -573,7 +573,7 @@
      Type:
      • -boolean +Boolean
      • @@ -646,8 +646,8 @@

        req -

        A IncomingMessage created by http.Server or http.ClientRequest usually passed as the -first parameter to the 'request' and 'response' events. Implements Readable Stream interface +

        A IncomingMessage created by http.Server or http.ClientRequest usually passed as the +first parameter to the 'request' and 'response' events. Implements Readable Stream interface but may not be a decendant thereof.

@@ -833,7 +833,7 @@
Type:
-

statusCode :number

+

statusCode :Number

@@ -905,7 +905,7 @@
Type:
  • -number +Number
  • @@ -923,7 +923,7 @@
    Example
    -

    statusMessage :string

    +

    statusMessage :String

    @@ -996,7 +996,7 @@
    Type:
    • -string +String
    • @@ -1014,7 +1014,7 @@
      Example
      -

      (readonly) trailers :object

      +

      (readonly) trailers :Object

      @@ -1078,9 +1078,9 @@

      (readonly) tr
      -

      Request/response trailer headers. Just like headers except these are only written +

      Request/response trailer headers. Just like headers except these are only written after the initial response to the client. -This object is only populated at the 'end' event and only work if a 'transfer-encoding: chunked' +This object is only populated at the 'end' event and only work if a 'transfer-encoding: chunked' header is sent in the initial response.

      @@ -1090,7 +1090,7 @@

      Type:
      • -object +Object
      • @@ -1103,7 +1103,7 @@
        Type:
        -

        (readonly) upgrade :boolean

        +

        (readonly) upgrade :Boolean

        @@ -1170,7 +1170,7 @@
        Type:
        • -boolean +Boolean
        • @@ -1183,7 +1183,7 @@
          Type:
          -

          (readonly) url :string

          +

          (readonly) url :String

          @@ -1243,7 +1243,7 @@
          Type:
          • -string +String
          • @@ -1267,7 +1267,7 @@
            Examples
            -

            (readonly) httpVersion :string

            +

            (readonly) httpVersion :String

            @@ -1334,7 +1334,7 @@
            Type:
            • -string +String
            • @@ -1347,7 +1347,7 @@
              Type:
              -

              (readonly) httpVersionMajor :number

              +

              (readonly) httpVersionMajor :Number

              @@ -1414,7 +1414,7 @@
              Type:
              • -number +Number
              • @@ -1427,7 +1427,7 @@
                Type:
                -

                (readonly) httpVersionMinor :string

                +

                (readonly) httpVersionMinor :String

                @@ -1494,7 +1494,7 @@
                Type:
                • -string +String
                • @@ -1626,7 +1626,7 @@
                  Parameters:
                  -object +Object @@ -1980,7 +1980,7 @@
                  Parameters:
                  -string +String @@ -2040,7 +2040,7 @@
                  Parameters:
                  -

                  getHeader(name) → {string}

                  +

                  getHeader(name) → {String}

                  @@ -2148,7 +2148,7 @@
                  Parameters:
                  -string +String @@ -2189,7 +2189,7 @@
                  Returns:
                  -string +String
                  @@ -2262,7 +2262,7 @@

                  pause -

                  Switch readable stream out of flowing mode and stop emitting 'data' events. +

                  Switch readable stream out of flowing mode and stop emitting 'data' events. Any new data that becomes available during this time will stay buffered until resume is called.

                  @@ -2403,7 +2403,7 @@
                  Parameters:
                  -string +String @@ -2640,7 +2640,7 @@
                  Parameters:
                  -string +String @@ -2749,7 +2749,7 @@

                  setEncodin

                  Example
                  -
                  request.setEncoding('utf8'); 
                  +
                  request.setEncoding('utf8');
                  @@ -2785,7 +2785,7 @@
                  Parameters:
                  -string +String @@ -2883,7 +2883,7 @@

                  setHeader -

                  Set a single header. If the header already exists, it will be replaced. +

                  Set a single header. If the header already exists, it will be replaced. It's possible to use an array of strings in place of value to send multiple headers with the same name.

                  @@ -2939,7 +2939,7 @@
                  Parameters:
                  -string +String @@ -3095,7 +3095,7 @@

                  uncorkwrite(chunk, encodingopt, callbackopt) → {boolean}

                  +

                  write(chunk, encodingopt, callbackopt) → {Boolean}

                  @@ -3159,7 +3159,7 @@

                  write

                  Note: If write() is called either before writeHead() or writeHead() just hasn't been called, it will switch * modes and flush the implicit headers that may be waiting before parts of this chunk are sent.

                  Node will buffer up to the first chunk of the body. Any additional calls to write() may be buffered as well for packet efficiency purposes.

                  -Returns true if the entire data was flushed successfully to the kernel buffer. Returns false if all or part of +Returns true if the entire data was flushed successfully to the kernel buffer. Returns false if all or part of the data was buffered in memory.

                  @@ -3246,7 +3246,7 @@
                  Parameters:
                  -string +String @@ -3345,7 +3345,7 @@
                  Returns:
                  -boolean +Boolean
                  @@ -3526,7 +3526,7 @@
                  Example
                  var content = 'Under Construction...';
                   response.writeHead(200, {
                       'Content-Length': Buffer.byteLength(content),
                  -    'Content-Type': 'text/plain' 
                  +    'Content-Type': 'text/plain'
                   });
                   response.end(content);
                  @@ -3566,7 +3566,7 @@
                  Parameters:
                  -number +Number @@ -3597,7 +3597,7 @@
                  Parameters:
                  -string +String @@ -3630,7 +3630,7 @@
                  Parameters:
                  -object +Object @@ -3738,7 +3738,7 @@

                  writeHeade
                  -

                  Warning: This has been deprecated in node, don't use it. Any apis that require this funtion should be +

                  Warning: This has been deprecated in node, don't use it. Any apis that require this funtion should be updated to use writeHead insted.

                  @@ -3995,7 +3995,7 @@

                  Parameters:
                  -

                  The chunk is either a buffer or string when the stream isn't operating +

                  The chunk is either a buffer or string when the stream isn't operating in object mode. When the stream is in object mode, the chunk can be any JavaScript value other than null.

                  @@ -4082,7 +4082,7 @@

                  drain

                  -

                  If a call to response.write(chunk) returns false, the drain event will be emitted once it is appropriate to +

                  If a call to response.write(chunk) returns false, the drain event will be emitted once it is appropriate to resume writing data to the stream.

                  diff --git a/docs/code/Service.html b/docs/code/Service.html index 7ed4ed7..66552ea 100644 --- a/docs/code/Service.html +++ b/docs/code/Service.html @@ -22,7 +22,7 @@
                  @@ -53,7 +53,7 @@

                  -

                  new Service()

                  +

                  new Service(opts, req, res)

                  @@ -65,7 +65,7 @@

                  new ServiceSource:
                  @@ -104,6 +104,9 @@

                  new Service +

                  Handles invoking the git-*-pack binaries

                  +

                  @@ -115,6 +118,102 @@

                  new ServiceParameters:

                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                  NameTypeDescription
                  opts + + +Object + + + +

                  options to bootstrap the service object

                  req + + +http.IncomingMessage + + + +

                  http request object

                  res + + +http.ServerResponse + + + +

                  http response

                  + + + @@ -242,7 +341,7 @@
                  Type:
                  -

                  (readonly) method :string

                  +

                  (readonly) method :String

                  @@ -316,7 +415,7 @@
                  Type:
                  • -string +String
                  • @@ -334,7 +433,7 @@
                    Example
                    -

                    (readonly) readable :boolean

                    +

                    (readonly) readable :Boolean

                    @@ -399,7 +498,7 @@
                    Type:
                    • -boolean +Boolean
                    • @@ -477,8 +576,8 @@

                      req -

                      A IncomingMessage created by http.Server or http.ClientRequest usually passed as the -first parameter to the 'request' and 'response' events. Implements Readable Stream interface +

                      A IncomingMessage created by http.Server or http.ClientRequest usually passed as the +first parameter to the 'request' and 'response' events. Implements Readable Stream interface but may not be a decendant thereof.

                      @@ -674,7 +773,7 @@
                      Type:
                      -

                      statusCode :number

                      +

                      statusCode :Number

                      @@ -751,7 +850,7 @@
                      Type:
                      • -number +Number
                      • @@ -769,7 +868,7 @@
                        Example
                        -

                        statusMessage :string

                        +

                        statusMessage :String

                        @@ -847,7 +946,7 @@
                        Type:
                        • -string +String
                        • @@ -865,7 +964,7 @@
                          Example
                          -

                          (readonly) trailers :object

                          +

                          (readonly) trailers :Object

                          @@ -934,9 +1033,9 @@

                          (readonly) tr
                          -

                          Request/response trailer headers. Just like headers except these are only written +

                          Request/response trailer headers. Just like headers except these are only written after the initial response to the client. -This object is only populated at the 'end' event and only work if a 'transfer-encoding: chunked' +This object is only populated at the 'end' event and only work if a 'transfer-encoding: chunked' header is sent in the initial response.

                          @@ -946,7 +1045,7 @@

                          Type:
                          • -object +Object
                          • @@ -959,7 +1058,7 @@
                            Type:
                            -

                            (readonly) upgrade :boolean

                            +

                            (readonly) upgrade :Boolean

                            @@ -1031,7 +1130,7 @@
                            Type:
                            • -boolean +Boolean
                            • @@ -1044,7 +1143,7 @@
                              Type:
                              -

                              (readonly) url :string

                              +

                              (readonly) url :String

                              @@ -1109,7 +1208,7 @@
                              Type:
                              • -string +String
                              • @@ -1135,6 +1234,250 @@
                                Examples
                                +

                                Methods

                                + + + + + + +

                                (static) accept()

                                + + + + + + +
                                + + +
                                Source:
                                +
                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                + + + + + +
                                +

                                accepts request to access resource

                                +
                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

                                (static) reject(code, msg)

                                + + + + + + +
                                + + +
                                Source:
                                +
                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                + + + + + +
                                +

                                reject request in flight

                                +
                                + + + + + + + + + + + +
                                Parameters:
                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                NameTypeDescription
                                code + + +Number + + + +

                                http response code

                                msg + + +String + + + +

                                message that should be displayed on teh client

                                + + + + + + + + + + + + + + + + + + diff --git a/docs/code/git.js.html b/docs/code/git.js.html index c178c28..c5abe24 100644 --- a/docs/code/git.js.html +++ b/docs/code/git.js.html @@ -22,7 +22,7 @@
                                @@ -52,14 +52,109 @@

                                git.js

                                const services = ['upload-pack', 'receive-pack']; /** - * @class Git - */ + * @event Git#push + * @type {Object} + * @property {HttpDuplex} push - is a http duplex object (see below) with these extra properties + * @property {String} push.repo - the string that defines the repo + * @property {String} push.commit - the string that defines the commit sha + * @property {String} push.branch - the string that defines the branch + * @example + repos.on('push', function (push) { ... } + + Emitted when somebody does a `git push` to the repo. + + Exactly one listener must call `push.accept()` or `push.reject()`. If there are + no listeners, `push.accept()` is called automatically. + * +**/ + +/** + * @event Git#tag + * @type {Object} + * @property {HttpDuplex} tag - an http duplex object (see below) with these extra properties: + * @property {String} tag.repo - the string that defines the repo + * @property {String} tag.commit - the string that defines the commit sha + * @property {String} tag.version - the string that defines the repo + * @example + repos.on('tag', function (tag) { ... } + + Emitted when somebody does a `git push --tags` to the repo. + Exactly one listener must call `tag.accept()` or `tag.reject()`. If there are + No listeners, `tag.accept()` is called automatically. + * +**/ + +/** + * @event Git#fetch + * @type {Object} + * @property {HttpDuplex} fetch - an http duplex object (see below) with these extra properties: + * @property {String} fetch.repo - the string that defines the repo + * @property {String} fetch.commit - the string that defines the commit sha + * @example + repos.on('fetch', function (fetch) { ... } + + Emitted when somebody does a `git fetch` to the repo (which happens whenever you + do a `git pull` or a `git clone`). + + Exactly one listener must call `fetch.accept()` or `fetch.reject()`. If there are + no listeners, `fetch.accept()` is called automatically. + * +*/ + +/** + * @event Git#info + * @type {Object} + * @property {HttpDuplex} info - an http duplex object (see below) with these extra properties: + * @property {String} info.repo - the string that defines the repo + * @example + repos.on('info', function (info) { ... } + + Emitted when the repo is queried for info before doing other commands. + + Exactly one listener must call `info.accept()` or `info.reject()`. If there are + no listeners, `info.accept()` is called automatically. + * +*/ + +/** + * @event Git#info + * @type {Object} + * @property {HttpDuplex} info - an http duplex object (see below) with these extra properties: + * @property {String} info.repo - the string that defines the repo + * @example + repos.on('info', function (info) { ... } + + Emitted when the repo is queried for info before doing other commands. + + Exactly one listener must call `info.accept()` or `info.reject()`. If there are + no listeners, `info.accept()` is called automatically. + * +*/ + +/** + * @event Git#head + * @type {Object} + * @property {HttpDuplex} head - an http duplex object (see below) with these extra properties: + * @property {String} head.repo - the string that defines the repo + * @example + repos.on('head', function (head) { ... } + + Emitted when the repo is queried for HEAD before doing other commands. + + Exactly one listener must call `head.accept()` or `head.reject()`. If there are + no listeners, `head.accept()` is called automatically. + * +*/ + class Git extends EventEmitter { /** - * returns an instance of Git + * + * Handles invoking the git-*-pack binaries + * @class Git + * @extends EventEmitter * @param {(String|Function)} repoDir - Create a new repository collection from the directory `repoDir`. `repoDir` should be entirely empty except for git repo directories. If `repoDir` is a function, `repoDir(repo)` will be used to dynamically resolve project directories. The return value of `repoDir(repo)` should be a string path specifying where to put the string `repo`. Make sure to return the same value for `repo` every time since `repoDir(repo)` will be called multiple times. * @param {Object} options - options that can be applied on the new instance being created - * @param {Boolean=} options.autoCreate - By default, repository targets will be created if they don't exist. You can + * @param {Boolean=} options.autoCreate - By default, repository targets will be created if they don't exist. You can disable that behavior with `options.autoCreate = true` * @param {Function} options.authenticate - a function that has the following arguments (repo, username, password, next) and will be called when a request comes through if set * @@ -77,106 +172,8 @@

                                git.js

                                return reject("sorry you don't have access to this content"); }); } - * @param {Boolean=} options.checkout - If `opts.checkout` is true, create and expected checked-out repos instead of - bare repos - * @return {Git} - * @description - # events - - ## repos.on('push', function (push) { ... } - - Emitted when somebody does a `git push` to the repo. - - Exactly one listener must call `push.accept()` or `push.reject()`. If there are - no listeners, `push.accept()` is called automatically. - - `push` is an http duplex object (see below) with these extra properties: - - * push.repo - * push.commit - * push.branch - - ## repos.on('tag', function (tag) { ... } - - Emitted when somebody does a `git push --tags` to the repo. - - Exactly one listener must call `tag.accept()` or `tag.reject()`. If there are - no listeners, `tag.accept()` is called automatically. - - `tag` is an http duplex object (see below) with these extra properties: - - * tag.repo - * tag.commit - * tag.version - - ## repos.on('fetch', function (fetch) { ... } - - Emitted when somebody does a `git fetch` to the repo (which happens whenever you - do a `git pull` or a `git clone`). - - Exactly one listener must call `fetch.accept()` or `fetch.reject()`. If there are - no listeners, `fetch.accept()` is called automatically. - - `fetch` is an http duplex objects (see below) with these extra properties: - - * fetch.repo - * fetch.commit - - ## repos.on('info', function (info) { ... } - - Emitted when the repo is queried for info before doing other commands. - - Exactly one listener must call `info.accept()` or `info.reject()`. If there are - no listeners, `info.accept()` is called automatically. - - `info` is an http duplex object (see below) with these extra properties: - - * info.repo - - ## repos.on('head', function (head) { ... } - - Emitted when the repo is queried for HEAD before doing other commands. - - Exactly one listener must call `head.accept()` or `head.reject()`. If there are - no listeners, `head.accept()` is called automatically. - - `head` is an http duplex object (see below) with these extra properties: - - * head.repo - - ## push.on('response', function(response, done) { ... }) - - Emitted when node-git-server creates a response stream that will be sent to the git client on the other end. - - This should really only be used if you want to send verbose or error messages to the remote git client. - - `response` is a writable stream that can accept buffers containing git packfile sidechannel transfer protocol encoded strings. `done` is a callback that must be called when you want to end the response. - - If you create a response listener then you must either call the `done` function or execute the following end sequence when you want to end the response: - - ```js - response.queue(new Buffer('0000')) - response.queue(null) - ``` - - If you never use the response event then the above data will be sent by default. Binding a listener to the response event will prevent the end sequence those from being sent, so you must send them yourself after sending any other messages. - - # http duplex objects - - The arguments to each of the events `'push'`, `'fetch'`, `'info'`, and `'head'` are [http duplex](http://github.com/substack/http-duplex) that act as both http - server request and http server response objects so you can pipe to and from them. - - For every event if there are no listeners `dup.accept()` will be called - automatically. - - ## dup.accept() - - Accept the pending request. - - ## dup.reject() - - Reject the pending request. - */ + * @param {Boolean=} options.checkout - If `opts.checkout` is true, create and expected checked-out repos instead of bare repos + */ constructor(repoDir, options={}) { super(); @@ -195,6 +192,7 @@

                                git.js

                                /** * Get a list of all the repositories * @method list + * @memberof Git * @param {Function} callback function to be called when repositories have been found `function(error, repos)` */ list(callback) { @@ -210,6 +208,7 @@

                                git.js

                                /** * Find out whether `repoName` exists in the callback `cb(exists)`. * @method exists + * @memberof Git * @param {String} repo - name of the repo * @param {Function=} callback - function to be called when finished */ @@ -219,6 +218,7 @@

                                git.js

                                /** * Create a subdirectory `dir` in the repo dir with a callback `cb(err)`. * @method mkdir + * @memberof Git * @param {String} dir - directory name * @param {Function=} callback - callback to be called when finished */ @@ -236,6 +236,7 @@

                                git.js

                                /** * Create a new bare repository `repoName` in the instance repository directory. * @method create + * @memberof Git * @param {String} repo - the name of the repo * @param {Function=} callback - Optionally get a callback `cb(err)` to be notified when the repository was created. */ @@ -277,6 +278,7 @@

                                git.js

                                /** * Handle incoming HTTP requests with a connect-style middleware * @method handle + * @memberof Git * @param {Object} req - http request object * @param {Object} res - http response object */ @@ -315,11 +317,7 @@

                                git.js

                                res.end(error); return; } else { - return infoResponse({ - repos: self, - repo: repo, - service: service, - }, req, res); + return infoResponse(self, repo, service, req, res); } }; @@ -448,6 +446,13 @@

                                git.js

                                if (x === false) next(ix + 1); })(0); } + /** + * starts a git server on the given port + * @method listen + * @memberof Git + * @param {Number} port - the port to start the server on + * @param {Function} callback - the function to call when server is started or error has occured + */ listen(port, callback) { var self = this; this.server = http.createServer(function(req, res) { @@ -455,6 +460,11 @@

                                git.js

                                }); this.server.listen(port, callback); } + /** + * closes the server instance + * @method close + * @memberof Git + */ close() { this.server.close(); } diff --git a/docs/code/global.html b/docs/code/global.html deleted file mode 100644 index 3610f86..0000000 --- a/docs/code/global.html +++ /dev/null @@ -1,954 +0,0 @@ - - - - - Global - Documentation - - - - - - - - - - - - - - - - -
                                - -

                                Global

                                - - - - - - - -
                                - -
                                - -

                                - -

                                - - -
                                - -
                                -
                                - - - -
                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                - - - - - - - - -
                                - - - - - - - - - - - - - - -

                                Methods

                                - - - - - - -

                                create(repo, callbackopt)

                                - - - - - - -
                                - - -
                                Source:
                                -
                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                - - - - - -
                                -

                                Create a new bare repository repoName in the instance repository directory.

                                -
                                - - - - - - - - - - - -
                                Parameters:
                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                NameTypeAttributesDescription
                                repo - - -String - - - - - - - - - -

                                the name of the repo

                                callback - - -function - - - - - - <optional>
                                - - - - - -

                                Optionally get a callback cb(err) to be notified when the repository was created.

                                - - - - - - - - - - - - - - - - - - - - - -

                                exists(repo, callbackopt)

                                - - - - - - -
                                - - -
                                Source:
                                -
                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                - - - - - -
                                -

                                Find out whether repoName exists in the callback cb(exists).

                                -
                                - - - - - - - - - - - -
                                Parameters:
                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                NameTypeAttributesDescription
                                repo - - -String - - - - - - - - - -

                                name of the repo

                                callback - - -function - - - - - - <optional>
                                - - - - - -

                                function to be called when finished

                                - - - - - - - - - - - - - - - - - - - - - -

                                handle(req, res)

                                - - - - - - -
                                - - -
                                Source:
                                -
                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                - - - - - -
                                -

                                Handle incoming HTTP requests with a connect-style middleware

                                -
                                - - - - - - - - - - - -
                                Parameters:
                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                NameTypeDescription
                                req - - -Object - - - -

                                http request object

                                res - - -Object - - - -

                                http response object

                                - - - - - - - - - - - - - - - - - - - - - -

                                list(callback)

                                - - - - - - -
                                - - -
                                Source:
                                -
                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                - - - - - -
                                -

                                Get a list of all the repositories

                                -
                                - - - - - - - - - - - -
                                Parameters:
                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                NameTypeDescription
                                callback - - -function - - - -

                                function to be called when repositories have been found function(error, repos)

                                - - - - - - - - - - - - - - - - - - - - - -

                                mkdir(dir, callbackopt)

                                - - - - - - -
                                - - -
                                Source:
                                -
                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                - - - - - -
                                -

                                Create a subdirectory dir in the repo dir with a callback cb(err).

                                -
                                - - - - - - - - - - - -
                                Parameters:
                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                NameTypeAttributesDescription
                                dir - - -String - - - - - - - - - -

                                directory name

                                callback - - -function - - - - - - <optional>
                                - - - - - -

                                callback to be called when finished

                                - - - - - - - - - - - - - - - - - - - - - - -
                                - -
                                - - - - -
                                - -
                                - - - - - - - \ No newline at end of file diff --git a/docs/code/http-duplex.js.html b/docs/code/http-duplex.js.html index 32bba0f..c0e7423 100644 --- a/docs/code/http-duplex.js.html +++ b/docs/code/http-duplex.js.html @@ -22,7 +22,7 @@
                                @@ -40,7 +40,7 @@

                                http-duplex.js

                                const EventEmitter = require('events');
                                 
                                 class HttpDuplex extends EventEmitter {
                                -    /** 
                                +    /**
                                      * Constructs a proxy object over input and output resulting in a unified stream.
                                      * Generally meant to combine request and response streams in the http.request event
                                      * @class HttpDuplex
                                @@ -61,8 +61,8 @@ 

                                http-duplex.js

                                super(); /** - * A IncomingMessage created by http.Server or http.ClientRequest usually passed as the - * first parameter to the 'request' and 'response' events. Implements Readable Stream interface + * A IncomingMessage created by http.Server or http.ClientRequest usually passed as the + * first parameter to the 'request' and 'response' events. Implements Readable Stream interface * but may not be a decendant thereof. * @type {http.IncomingMessage} * @see {@link https://nodejs.org/api/http.html#http_event_request|request} @@ -113,14 +113,14 @@

                                http-duplex.js

                                } /** - * Request/response headers. Key-value pairs of header names and values. Header names are always lower-case. + * Request/response headers. Key-value pairs of header names and values. Header names are always lower-case. * @name headers * @alias HttpDuplex.headers * @memberof HttpDuplex - * @type {object} + * @type {Object} * @readonly * @see {@link https://nodejs.org/api/http.html#http_message_headers|message.headers} - */ + */ get headers() { return this.req.headers; } @@ -130,7 +130,7 @@

                                http-duplex.js

                                * @name httpVersion * @alias HttpDuplex.httpVersion * @memberof HttpDuplex - * @type {string} + * @type {String} * @see {@link https://nodejs.org/api/http.html#http_message_httpversion|message.httpVersion} * @readonly */ @@ -143,7 +143,7 @@

                                http-duplex.js

                                * @name httpVersionMajor * @alias HttpDuplex.httpVersionMajor * @memberof HttpDuplex - * @type {number} + * @type {Number} * @see httpVersion * @readonly */ @@ -156,29 +156,29 @@

                                http-duplex.js

                                * @name httpVersionMinor * @alias HttpDuplex.httpVersionMinor * @memberof HttpDuplex - * @type {string} + * @type {String} * @see httpVersion * @readonly */ get httpVersionMinor() { return this.req.httpVersionMinor; } - + /** * Request method of the incoming request. - * @type {string} + * @type {String} * @see {@link https://nodejs.org/api/http.html#http_event_request|request} * @see {@link https://nodejs.org/api/http.html#http_class_http_serverresponse|http.ServerResponse} * @example 'GET', 'DELETE' * @readonly - */ + */ get method() { return this.req.method; } /** * Is this stream readable. - * @type {boolean} + * @type {Boolean} * @readonly */ get readable() { @@ -187,7 +187,7 @@

                                http-duplex.js

                                /** * net.Socket object associated with the connection. - * @type net.Socket + * @type net.Socket * @see {@link https://nodejs.org/api/net.html#net_class_net_socket|net.Socket} * @readonly */ @@ -196,8 +196,8 @@

                                http-duplex.js

                                } /** - * The HTTP status code. Generally assigned before sending headers for a response to a client. - * @type {number} + * The HTTP status code. Generally assigned before sending headers for a response to a client. + * @type {Number} * @default 200 * @see {@link https://nodejs.org/api/http.html#http_response_statuscode|response.statusCode} * @example request.statusCode = 404; @@ -213,7 +213,7 @@

                                http-duplex.js

                                /** * Controls the status message sent to the client as long as an explicit call to response.writeHead() isn't made * If ignored or the value is undefined, the default message corresponding to the status code will be used. - * @type {string} + * @type {String} * @default undefined * @see {@link https://nodejs.org/api/http.html#http_response_statusmessage|response.statusMessage} * @example request.statusMessage = 'Document Not found'; @@ -227,12 +227,12 @@

                                http-duplex.js

                                } /** - * Request/response trailer headers. Just like {@link headers} except these are only written + * Request/response trailer headers. Just like {@link headers} except these are only written * after the initial response to the client. - * This object is only populated at the 'end' event and only work if a 'transfer-encoding: chunked' + * This object is only populated at the 'end' event and only work if a 'transfer-encoding: chunked' * header is sent in the initial response. * @name HttpDuplex#trailers - * @type {object} + * @type {Object} * @readonly * @see headers * @see addTrailers @@ -245,7 +245,7 @@

                                http-duplex.js

                                /** * Whether or not the client connection has been upgraded - * @type {boolean} + * @type {Boolean} * @see {@link https://nodejs.org/api/http.html#http_event_upgrade_1|upgrade} * @readonly */ @@ -257,9 +257,9 @@

                                http-duplex.js

                                * Request URL string. * @example <caption>A request made as:</caption> * GET /info?check=none HTTP/1.1 - * @example <caption>Will return the string</caption> + * @example <caption>Will return the string</caption> * '/info?check=none' - * @type {string} + * @type {String} * @readonly */ get url() { @@ -319,14 +319,14 @@

                                http-duplex.js

                                * passed as a Buffer. * @event data * @alias HttpDuplex#event:data - * @param {(string|buffer|any)} chunk The chunk is either a buffer or string when the stream isn't operating + * @param {(string|buffer|any)} chunk The chunk is either a buffer or string when the stream isn't operating * in object mode. When the stream is in object mode, the chunk can be any JavaScript value other than null. * @memberof HttpDuplex * @see {@link https://nodejs.org/api/stream.html#stream_event_data|stream.Readable/data} */ /** - * If a call to response.write(chunk) returns false, the drain event will be emitted once it is appropriate to + * If a call to response.write(chunk) returns false, the drain event will be emitted once it is appropriate to * resume writing data to the stream. * @event drain * @alias HttpDuplex#event:drain @@ -361,12 +361,12 @@

                                http-duplex.js

                                /** * Adds trailing headers to the response. - * Trailers will only be emitted if chunked encoding is enabled for the response; otherwise they are discarded. + * Trailers will only be emitted if chunked encoding is enabled for the response; otherwise they are discarded. * @method addTrailers * @name addTrailers * @alias HttpDuplex.addTrailers * @memberof HttpDuplex - * @param {object} headers Trailing headers to add to the response + * @param {Object} headers Trailing headers to add to the response * @see trailers * @see headers * @see {@link https://nodejs.org/api/http.html#http_message_trailers|message.trailers} @@ -396,7 +396,7 @@

                                http-duplex.js

                                * @alias HttpDuplex.end * @memberof HttpDuplex * @param {(string|Buffer)} data optional data to write to the response before closing the connection - * @param {string} encoding Encoding that should be used to write the data + * @param {String} encoding Encoding that should be used to write the data * @param {function} callback Function to be called once the response stream is finished * @see {@link https://nodejs.org/api/http.html#http_response_end_data_encoding_callback|response.end} */ @@ -406,28 +406,28 @@

                                http-duplex.js

                                * @method getHeader * @alias HttpDuplex.getHeader * @memberof HttpDuplex - * @param {string} name Header to get the value of - * @returns {string} + * @param {String} name Header to get the value of + * @returns {String} * @see {@link https://nodejs.org/api/http.html#http_request_getheader_name|getHeader} * @example * let contentType = request.getHeader('Content-Type'); */ /** - * Switch readable stream out of flowing mode and stop emitting 'data' events. + * Switch readable stream out of flowing mode and stop emitting 'data' events. * Any new data that becomes available during this time will stay buffered until resume is called. * @method pause * @alias HttpDuplex.pause * @memberof HttpDuplex * @see {@link https://nodejs.org/api/stream.html#stream_readable_pause|stream.Readable.pause} */ - + /** * Remove a header from the response headers. * @method removeHeader * @alias HttpDuplex.removeHeader * @memberof HttpDuplex - * @param {string} name Header to remove + * @param {String} name Header to remove * @see {@link https://nodejs.org/api/http.html#http_request_removeheader_name|removeHeader} * @example * request.removeHeader('Content-Type'); @@ -441,13 +441,13 @@

                                http-duplex.js

                                * @memberof HttpDuplex * @see {@link https://nodejs.org/api/stream.html#stream_readable_resume|stream.Readable.resume} */ - + /** * Sets the character encoding for data written to the stream. * @method setDefaultEncoding * @alias HttpDuplex.setDefaultEncoding * @memberof HttpDuplex - * @param encoding {string} new character encoding + * @param encoding {String} new character encoding * @see setEncoding * @example request.setDefaultEncoding('utf8'); */ @@ -457,18 +457,18 @@

                                http-duplex.js

                                * @method setEncoding * @alias HttpDuplex.setEncoding * @memberof HttpDuplex - * @param encoding {string} new character encoding + * @param encoding {String} new character encoding * @see setDefaultEncoding - * @example request.setEncoding('utf8'); + * @example request.setEncoding('utf8'); */ /** - * Set a single header. If the header already exists, it will be replaced. + * Set a single header. If the header already exists, it will be replaced. * It's possible to use an array of strings in place of value to send multiple headers with the same name. * @method setHeader * @alias HttpDuplex.setHeader * @memberof HttpDuplex - * @param {string} name Header to set + * @param {String} name Header to set * @param {string|string[]} value Value(s) to assign to header * @see removeHeader * @see {@link https://nodejs.org/api/http.html#http_request_setheader_name_value|setHeader} @@ -477,7 +477,7 @@

                                http-duplex.js

                                * @example <caption>Array of string value</caption> * request.setHeader('Set-Cookie', ['type=auth', 'language=javascript']); */ - + /** * Flushes all data buffered since cork() was called. * @method uncork @@ -493,19 +493,19 @@

                                http-duplex.js

                                * <p>*Note:* If write() is called either before writeHead() or writeHead() just hasn't been called, it will switch * modes and flush the implicit headers that may be waiting before parts of this chunk are sent.<p/> * Node will buffer up to the first chunk of the body. Any additional calls to write() may be buffered as well * for packet efficiency purposes.</p> - * Returns true if the entire data was flushed successfully to the kernel buffer. Returns false if all or part of + * Returns true if the entire data was flushed successfully to the kernel buffer. Returns false if all or part of * the data was buffered in memory. * @method write * @alias HttpDuplex.write * @memberof HttpDuplex * @param {(string|Buffer)} chunk chunk of data to send. - * @param {string} [encoding='utf8'] If chunk is a string, this specifies how to encode it into a byte stream. + * @param {String} [encoding='utf8'] If chunk is a string, this specifies how to encode it into a byte stream. * @param {function} [callback] Callback to call when this chunk of data is flushed. - * @returns {boolean} + * @returns {Boolean} * @emits {@link event:drain|drain} Emitted when data was buffered and the buffer has become free for use again. * @see {@link https://nodejs.org/api/http.html#http_response_write_chunk_encoding_callback|http.ServerResponse.write} */ - + /** * Sends an HTTP/1.1 100 Continue message to the client. * @method writeContinue @@ -520,24 +520,24 @@

                                http-duplex.js

                                * @method writeHead * @alias HttpDuplex.writeHead * @memberof HttpDuplex - * @param {number} statusCode 3-digit HTTP status code, like 404 - * @param {string} [statusMessage] An optional human readable status message to send with the status code - * @param {object} [headers] An object containing the response headers to send + * @param {Number} statusCode 3-digit HTTP status code, like 404 + * @param {String} [statusMessage] An optional human readable status message to send with the status code + * @param {Object} [headers] An object containing the response headers to send * @see {@link https://nodejs.org/api/http.html#http_response_writehead_statuscode_statusmessage_headers|response.writeHead} * @example var content = 'Under Construction...'; * response.writeHead(200, { * 'Content-Length': Buffer.byteLength(content), - * 'Content-Type': 'text/plain' + * 'Content-Type': 'text/plain' * }); * response.end(content); */ - + /** - * __Warning:__ This has been deprecated in node, __don't__ use it. Any apis that require this funtion should be + * __Warning:__ This has been deprecated in node, __don't__ use it. Any apis that require this funtion should be * updated to use writeHead insted. * @method writeHeader * @alias HttpDuplex.writeHeader - * @memberof HttpDuplex + * @memberof HttpDuplex * @deprecated {@link https://nodejs.org/api/deprecations.html#deprecations_dep0063_serverresponse_prototype_writeheader|Node Deprecated} * @see writeHead */ diff --git a/docs/code/index.html b/docs/code/index.html index 00942a6..e0081de 100644 --- a/docs/code/index.html +++ b/docs/code/index.html @@ -22,7 +22,7 @@
                                diff --git a/docs/code/module-lib_util.html b/docs/code/module-lib_util.html index 3188803..f97013f 100644 --- a/docs/code/module-lib_util.html +++ b/docs/code/module-lib_util.html @@ -22,7 +22,7 @@
                                @@ -168,7 +168,7 @@
                                Parameters:
                                -Object +http.IncomingMessage @@ -191,7 +191,7 @@
                                Parameters:
                                -Object +http.ServerResponse @@ -201,7 +201,7 @@
                                Parameters:
                                -

                                http response object

                                +

                                http response

                                @@ -263,7 +263,7 @@

                                (inner)
                                Source:
                                @@ -370,7 +370,7 @@

                                Parameters:
                                -Object +http.IncomingMessage @@ -393,7 +393,7 @@
                                Parameters:
                                -Object +http.ServerResponse @@ -403,7 +403,7 @@
                                Parameters:
                                -

                                http response object

                                +

                                http response

                                @@ -447,6 +447,231 @@
                                Returns:
                                + +

                                (inner) infoResponse(git, repo, service, req, res)

                                + + + + + + +
                                + + +
                                Source:
                                +
                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                + + + + + +
                                +

                                sends http response using the appropriate output from service call

                                +
                                + + + + + + + + + + + +
                                Parameters:
                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                NameTypeDescription
                                git + + +Git + + + +

                                an instance of git object

                                repo + + +String + + + +

                                the repository

                                service + + +String + + + +

                                the method that is responding infoResponse (push, pull, clone)

                                req + + +http.IncomingMessage + + + +

                                http request object

                                res + + +http.ServerResponse + + + +

                                http response

                                + + + + + + + + + + + + + + + + + + + +

                                (inner) noCache(res)

                                @@ -544,7 +769,7 @@
                                Parameters:
                                -Object +http.ServerResponse @@ -554,7 +779,7 @@
                                Parameters:
                                -

                                http response object

                                +

                                http response

                                @@ -749,7 +974,7 @@

                                (inner)
                                Source:
                                @@ -867,9 +1092,7 @@

                                Returns:
                                -
                                  -
                                • returns the name of the repo
                                • -
                                +

                                returns the name of the repo

                                @@ -890,6 +1113,208 @@
                                Returns:
                                + + + + +

                                (inner) serviceRespond(dup, service, repoLocation, res)

                                + + + + + + +
                                + + +
                                Source:
                                +
                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                + + + + + +
                                +

                                execute given git operation and respond

                                +
                                + + + + + + + + + + + +
                                Parameters:
                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                NameTypeDescription
                                dup + + +HttpDuplex + + + +

                                duplex object to catch errors

                                service + + +String + + + +

                                the method that is responding infoResponse (push, pull, clone)

                                repoLocation + + +String + + + +

                                the repo path on disk

                                res + + +http.ServerResponse + + + +

                                http response

                                + + + + + + + + + + + + + + + + + diff --git a/docs/code/service.js.html b/docs/code/service.js.html index f1c0f4d..e293e33 100644 --- a/docs/code/service.js.html +++ b/docs/code/service.js.html @@ -22,7 +22,7 @@
                                @@ -42,25 +42,21 @@

                                service.js

                                const zlib = require('zlib'); const { spawn } = require('child_process'); -const { inherits } = require('util'); - -const encodings = { - 'gzip': () => zlib.createGunzip(), - 'deflate': () => zlib.createDeflate() -}; const headerRE = { - 'receive-pack': '([0-9a-fA-F]+) ([0-9a-fA-F]+)' + - ' refs\/(heads|tags)\/(.*?)( |00|\u0000)' + // eslint-disable-line - '|^(0000)$', - 'upload-pack': '^\\S+ ([0-9a-fA-F]+)' + 'receive-pack': '([0-9a-fA-F]+) ([0-9a-fA-F]+) refs\/(heads|tags)\/(.*?)( |00|\u0000)|^(0000)$', // eslint-disable-line + 'upload-pack': '^\\S+ ([0-9a-fA-F]+)' }; -/** - * @class Service - * @extends HttpDuplex - */ class Service extends HttpDuplex { + /** + * Handles invoking the git-*-pack binaries + * @class Service + * @extends HttpDuplex + * @param {Object} opts - options to bootstrap the service object + * @param {http.IncomingMessage } req - http request object + * @param {http.ServerResponse} res - http response + */ constructor(opts, req, res) { super(req, res); @@ -77,7 +73,11 @@

                                service.js

                                // stream needed to receive data after decoding, but before accepting var ts = through(); - var decoder = encodings[req.headers['content-encoding']]; + var decoder = { + 'gzip': () => zlib.createGunzip(), + 'deflate': () => zlib.createDeflate() + }[req.headers['content-encoding']]; + if (decoder) { // data is compressed with gzip or deflate req.pipe(decoder()).pipe(ts).pipe(buffered); @@ -94,7 +94,7 @@

                                service.js

                                } } - ts.once('data', function(buf) { + ts.once('data', function onData(buf) { data += buf; var ops = data.match(new RegExp(headerRE[self.service], 'gi')); @@ -133,50 +133,52 @@

                                service.js

                                }); }); - self.once('accept', function() { + self.once('accept', function onAccept() { process.nextTick(function() { var cmd = ['git-' + opts.service, '--stateless-rpc', opts.cwd]; var ps = spawn(cmd[0], cmd.slice(1)); ps.on('error', function(err) { - self.emit('error', new Error( - err.message + ' running command ' + cmd.join(' ') - )); + self.emit('error', new Error(`${err.message} running command ${cmd.join(' ')}`)); }); self.emit('service', ps); var respStream = through(function(c) { - if (self.listeners('response').length === 0) - return this.queue(c); + if (self.listeners('response').length === 0) return this.queue(c); // prevent git from sending the close signal - if (c.length === 4 && c.toString() === '0000') - return; + if (c.length === 4 && c.toString() === '0000') return; this.queue(c); }, function() { - if (self.listeners('response').length > 0) - return; + if (self.listeners('response').length > 0) return; this.queue(null); }); - const endResponse = () => { + + self.emit('response', respStream, function endResponse() { res.queue(new Buffer('0000')); res.queue(null); - }; - - self.emit('response', respStream, endResponse); + }); ps.stdout.pipe(respStream).pipe(res); buffered.pipe(ps.stdin); buffered.resume(); + ps.on('exit', self.emit.bind(self, 'exit')); }); }); - self.once('reject', (code, msg) => { + self.once('reject', function onReject(code, msg) { res.statusCode = code; res.end(msg); }); } + /** + * reject request in flight + * @method reject + * @memberof Service + * @param {Number} code - http response code + * @param {String} msg - message that should be displayed on teh client + */ reject(code, msg) { if (this.status !== 'pending') return; @@ -187,16 +189,19 @@

                                service.js

                                this.status = 'rejected'; this.emit('reject', code || 500, msg); } - accept(dir) { + /** + * accepts request to access resource + * @method accept + * @memberof Service + */ + accept() { if (this.status !== 'pending') return; this.status = 'accepted'; - this.emit('accept', dir); + this.emit('accept'); } } -inherits(Service, HttpDuplex); - module.exports = Service;
                                diff --git a/docs/code/util.js.html b/docs/code/util.js.html index 685370e..fe4bd43 100644 --- a/docs/code/util.js.html +++ b/docs/code/util.js.html @@ -22,7 +22,7 @@
                                @@ -41,16 +41,16 @@

                                util.js

                                * @module lib/util */ -const httpDuplex = require('./http-duplex'); const { spawn } = require('child_process'); +const httpDuplex = require('./http-duplex'); const Service = require('./service'); const Util = { /** * adds headers to the response object to add cache control * @method noCache - * @param {Object} res - http response object + * @param {http.ServerResponse} res - http response */ noCache: function noCache(res) { res.setHeader('expires', 'Fri, 01 Jan 1980 00:00:00 GMT'); @@ -60,8 +60,8 @@

                                util.js

                                /** * sets and parses basic auth headers if they exist * @method basicAuth - * @param {Object} req - http request object - * @param {Object} res - http response object + * @param {http.IncomingMessage } req - http request object + * @param {http.ServerResponse} res - http response * @param {Function} callback - function(username, password, error) */ basicAuth: function basicAuth(req, res, callback) { @@ -87,8 +87,9 @@

                                util.js

                                * @param {Function} callback - function(code, signature) */ onExit: function onExit(ps, callback) { - var code, sig; - var pending = 3; + let code; + let sig; + let pending = 3; const onend = () => { if (--pending === 0) { @@ -105,7 +106,15 @@

                                util.js

                                ps.stdout.on('end', onend); ps.stderr.on('end', onend); }, - serviceRespond: function serviceRespond(self, service, file, res) { + /** + * execute given git operation and respond + * @method serviceRespond + * @param {HttpDuplex} dup - duplex object to catch errors + * @param {String} service - the method that is responding infoResponse (push, pull, clone) + * @param {String} repoLocation - the repo path on disk + * @param {http.ServerResponse} res - http response + */ + serviceRespond: function serviceRespond(dup, service, repoLocation, res) { const pack = (s) => { var n = (4 + s.length).toString(16); return Array(4 - n.length + 1).join('0') + n + s; @@ -114,20 +123,26 @@

                                util.js

                                res.write(pack('# service=git-' + service + '\n')); res.write('0000'); - const cmd = ['git-' + service, '--stateless-rpc', '--advertise-refs', file]; + const cmd = ['git-' + service, '--stateless-rpc', '--advertise-refs', repoLocation]; const ps = spawn(cmd[0], cmd.slice(1)); ps.on('error', (err) => { - self.emit('error', new Error( - err.message + ' running command ' + cmd.join(' ') - )); + dup.emit('error', new Error(`${err.message} running command ${cmd.join(' ')}`)); }); ps.stdout.pipe(res); }, - infoResponse: function infoResponse(opts, req, res) { - var self = opts.repos; + /** + * sends http response using the appropriate output from service call + * @method infoResponse + * @param {Git} git - an instance of git object + * @param {String} repo - the repository + * @param {String} service - the method that is responding infoResponse (push, pull, clone) + * @param {http.IncomingMessage } req - http request object + * @param {http.ServerResponse} res - http response + */ + infoResponse: function infoResponse(git, repo, service, req, res) { var dup = new httpDuplex(req, res); - dup.cwd = self.dirMap(opts.repo); - dup.repo = opts.repo; + dup.cwd = git.dirMap(repo); + dup.repo = repo; dup.accept = dup.emit.bind(dup, 'accept'); dup.reject = dup.emit.bind(dup, 'reject'); @@ -137,17 +152,17 @@

                                util.js

                                res.end(); }); - var anyListeners = self.listeners('info').length > 0; + var anyListeners = git.listeners('info').length > 0; - self.exists(opts.repo, (ex) => { + git.exists(repo, (ex) => { dup.exists = ex; - if (!ex && self.autoCreate) { + if (!ex && git.autoCreate) { dup.once('accept', () => { - self.create(opts.repo, next); + git.create(repo, next); }); - self.emit('info', dup); + git.emit('info', dup); if (!anyListeners) dup.accept(); } else if (!ex) { res.statusCode = 404; @@ -155,7 +170,7 @@

                                util.js

                                res.end('repository not found'); } else { dup.once('accept', next); - self.emit('info', dup); + git.emit('info', dup); if (!anyListeners) dup.accept(); } @@ -164,18 +179,22 @@

                                util.js

                                function next() { res.setHeader( 'content-type', - 'application/x-git-' + opts.service + '-advertisement' + 'application/x-git-' + service + '-advertisement' ); Util.noCache(res); - var d = self.dirMap(opts.repo); - Util.serviceRespond(self, opts.service, d, res); + Util.serviceRespond( + git, + service, + git.dirMap(repo), + res + ); } }, /** * parses a git string and returns the repo name * @method parseGitName * @param {String} repo - the raw repo name containing .git - * @return {String} - returns the name of the repo + * @return {String} returns the name of the repo */ parseGitName: function parseGitName(repo) { const locationOfGit = repo.lastIndexOf('.git'); @@ -185,8 +204,8 @@

                                util.js

                                * responds with the correct service depending on the action * @method createAction * @param {Object} opts - options to pass Service - * @param {Object} req - http request object - * @param {Object} res - http response object + * @param {http.IncomingMessage } req - http request object + * @param {http.ServerResponse} res - http response * @return {Service} */ createAction: function createAction(opts, req, res) { diff --git a/lib/git.js b/lib/git.js index 539a23d..7367544 100644 --- a/lib/git.js +++ b/lib/git.js @@ -13,14 +13,109 @@ const { parseGitName, createAction, infoResponse, onExit, basicAuth, noCache } = const services = ['upload-pack', 'receive-pack']; /** - * @class Git - */ + * @event Git#push + * @type {Object} + * @property {HttpDuplex} push - is a http duplex object (see below) with these extra properties + * @property {String} push.repo - the string that defines the repo + * @property {String} push.commit - the string that defines the commit sha + * @property {String} push.branch - the string that defines the branch + * @example + repos.on('push', function (push) { ... } + + Emitted when somebody does a `git push` to the repo. + + Exactly one listener must call `push.accept()` or `push.reject()`. If there are + no listeners, `push.accept()` is called automatically. + * +**/ + +/** + * @event Git#tag + * @type {Object} + * @property {HttpDuplex} tag - an http duplex object (see below) with these extra properties: + * @property {String} tag.repo - the string that defines the repo + * @property {String} tag.commit - the string that defines the commit sha + * @property {String} tag.version - the string that defines the repo + * @example + repos.on('tag', function (tag) { ... } + + Emitted when somebody does a `git push --tags` to the repo. + Exactly one listener must call `tag.accept()` or `tag.reject()`. If there are + No listeners, `tag.accept()` is called automatically. + * +**/ + +/** + * @event Git#fetch + * @type {Object} + * @property {HttpDuplex} fetch - an http duplex object (see below) with these extra properties: + * @property {String} fetch.repo - the string that defines the repo + * @property {String} fetch.commit - the string that defines the commit sha + * @example + repos.on('fetch', function (fetch) { ... } + + Emitted when somebody does a `git fetch` to the repo (which happens whenever you + do a `git pull` or a `git clone`). + + Exactly one listener must call `fetch.accept()` or `fetch.reject()`. If there are + no listeners, `fetch.accept()` is called automatically. + * +*/ + +/** + * @event Git#info + * @type {Object} + * @property {HttpDuplex} info - an http duplex object (see below) with these extra properties: + * @property {String} info.repo - the string that defines the repo + * @example + repos.on('info', function (info) { ... } + + Emitted when the repo is queried for info before doing other commands. + + Exactly one listener must call `info.accept()` or `info.reject()`. If there are + no listeners, `info.accept()` is called automatically. + * +*/ + +/** + * @event Git#info + * @type {Object} + * @property {HttpDuplex} info - an http duplex object (see below) with these extra properties: + * @property {String} info.repo - the string that defines the repo + * @example + repos.on('info', function (info) { ... } + + Emitted when the repo is queried for info before doing other commands. + + Exactly one listener must call `info.accept()` or `info.reject()`. If there are + no listeners, `info.accept()` is called automatically. + * +*/ + +/** + * @event Git#head + * @type {Object} + * @property {HttpDuplex} head - an http duplex object (see below) with these extra properties: + * @property {String} head.repo - the string that defines the repo + * @example + repos.on('head', function (head) { ... } + + Emitted when the repo is queried for HEAD before doing other commands. + + Exactly one listener must call `head.accept()` or `head.reject()`. If there are + no listeners, `head.accept()` is called automatically. + * +*/ + class Git extends EventEmitter { /** - * returns an instance of Git + * + * Handles invoking the git-*-pack binaries + * @class Git + * @extends EventEmitter * @param {(String|Function)} repoDir - Create a new repository collection from the directory `repoDir`. `repoDir` should be entirely empty except for git repo directories. If `repoDir` is a function, `repoDir(repo)` will be used to dynamically resolve project directories. The return value of `repoDir(repo)` should be a string path specifying where to put the string `repo`. Make sure to return the same value for `repo` every time since `repoDir(repo)` will be called multiple times. * @param {Object} options - options that can be applied on the new instance being created - * @param {Boolean=} options.autoCreate - By default, repository targets will be created if they don't exist. You can + * @param {Boolean=} options.autoCreate - By default, repository targets will be created if they don't exist. You can disable that behavior with `options.autoCreate = true` * @param {Function} options.authenticate - a function that has the following arguments (repo, username, password, next) and will be called when a request comes through if set * @@ -38,106 +133,8 @@ class Git extends EventEmitter { return reject("sorry you don't have access to this content"); }); } - * @param {Boolean=} options.checkout - If `opts.checkout` is true, create and expected checked-out repos instead of - bare repos - * @return {Git} - * @description - # events - - ## repos.on('push', function (push) { ... } - - Emitted when somebody does a `git push` to the repo. - - Exactly one listener must call `push.accept()` or `push.reject()`. If there are - no listeners, `push.accept()` is called automatically. - - `push` is an http duplex object (see below) with these extra properties: - - * push.repo - * push.commit - * push.branch - - ## repos.on('tag', function (tag) { ... } - - Emitted when somebody does a `git push --tags` to the repo. - - Exactly one listener must call `tag.accept()` or `tag.reject()`. If there are - no listeners, `tag.accept()` is called automatically. - - `tag` is an http duplex object (see below) with these extra properties: - - * tag.repo - * tag.commit - * tag.version - - ## repos.on('fetch', function (fetch) { ... } - - Emitted when somebody does a `git fetch` to the repo (which happens whenever you - do a `git pull` or a `git clone`). - - Exactly one listener must call `fetch.accept()` or `fetch.reject()`. If there are - no listeners, `fetch.accept()` is called automatically. - - `fetch` is an http duplex objects (see below) with these extra properties: - - * fetch.repo - * fetch.commit - - ## repos.on('info', function (info) { ... } - - Emitted when the repo is queried for info before doing other commands. - - Exactly one listener must call `info.accept()` or `info.reject()`. If there are - no listeners, `info.accept()` is called automatically. - - `info` is an http duplex object (see below) with these extra properties: - - * info.repo - - ## repos.on('head', function (head) { ... } - - Emitted when the repo is queried for HEAD before doing other commands. - - Exactly one listener must call `head.accept()` or `head.reject()`. If there are - no listeners, `head.accept()` is called automatically. - - `head` is an http duplex object (see below) with these extra properties: - - * head.repo - - ## push.on('response', function(response, done) { ... }) - - Emitted when node-git-server creates a response stream that will be sent to the git client on the other end. - - This should really only be used if you want to send verbose or error messages to the remote git client. - - `response` is a writable stream that can accept buffers containing git packfile sidechannel transfer protocol encoded strings. `done` is a callback that must be called when you want to end the response. - - If you create a response listener then you must either call the `done` function or execute the following end sequence when you want to end the response: - - ```js - response.queue(new Buffer('0000')) - response.queue(null) - ``` - - If you never use the response event then the above data will be sent by default. Binding a listener to the response event will prevent the end sequence those from being sent, so you must send them yourself after sending any other messages. - - # http duplex objects - - The arguments to each of the events `'push'`, `'fetch'`, `'info'`, and `'head'` are [http duplex](http://github.com/substack/http-duplex) that act as both http - server request and http server response objects so you can pipe to and from them. - - For every event if there are no listeners `dup.accept()` will be called - automatically. - - ## dup.accept() - - Accept the pending request. - - ## dup.reject() - - Reject the pending request. - */ + * @param {Boolean=} options.checkout - If `opts.checkout` is true, create and expected checked-out repos instead of bare repos + */ constructor(repoDir, options={}) { super(); @@ -156,6 +153,7 @@ class Git extends EventEmitter { /** * Get a list of all the repositories * @method list + * @memberof Git * @param {Function} callback function to be called when repositories have been found `function(error, repos)` */ list(callback) { @@ -171,6 +169,7 @@ class Git extends EventEmitter { /** * Find out whether `repoName` exists in the callback `cb(exists)`. * @method exists + * @memberof Git * @param {String} repo - name of the repo * @param {Function=} callback - function to be called when finished */ @@ -180,6 +179,7 @@ class Git extends EventEmitter { /** * Create a subdirectory `dir` in the repo dir with a callback `cb(err)`. * @method mkdir + * @memberof Git * @param {String} dir - directory name * @param {Function=} callback - callback to be called when finished */ @@ -197,6 +197,7 @@ class Git extends EventEmitter { /** * Create a new bare repository `repoName` in the instance repository directory. * @method create + * @memberof Git * @param {String} repo - the name of the repo * @param {Function=} callback - Optionally get a callback `cb(err)` to be notified when the repository was created. */ @@ -238,6 +239,7 @@ class Git extends EventEmitter { /** * Handle incoming HTTP requests with a connect-style middleware * @method handle + * @memberof Git * @param {Object} req - http request object * @param {Object} res - http response object */ @@ -276,11 +278,7 @@ class Git extends EventEmitter { res.end(error); return; } else { - return infoResponse({ - repos: self, - repo: repo, - service: service, - }, req, res); + return infoResponse(self, repo, service, req, res); } }; @@ -409,6 +407,13 @@ class Git extends EventEmitter { if (x === false) next(ix + 1); })(0); } + /** + * starts a git server on the given port + * @method listen + * @memberof Git + * @param {Number} port - the port to start the server on + * @param {Function} callback - the function to call when server is started or error has occured + */ listen(port, callback) { var self = this; this.server = http.createServer(function(req, res) { @@ -416,6 +421,11 @@ class Git extends EventEmitter { }); this.server.listen(port, callback); } + /** + * closes the server instance + * @method close + * @memberof Git + */ close() { this.server.close(); } diff --git a/lib/http-duplex.js b/lib/http-duplex.js index 39206c8..7cea0a1 100644 --- a/lib/http-duplex.js +++ b/lib/http-duplex.js @@ -1,7 +1,7 @@ const EventEmitter = require('events'); class HttpDuplex extends EventEmitter { - /** + /** * Constructs a proxy object over input and output resulting in a unified stream. * Generally meant to combine request and response streams in the http.request event * @class HttpDuplex @@ -22,8 +22,8 @@ class HttpDuplex extends EventEmitter { super(); /** - * A IncomingMessage created by http.Server or http.ClientRequest usually passed as the - * first parameter to the 'request' and 'response' events. Implements Readable Stream interface + * A IncomingMessage created by http.Server or http.ClientRequest usually passed as the + * first parameter to the 'request' and 'response' events. Implements Readable Stream interface * but may not be a decendant thereof. * @type {http.IncomingMessage} * @see {@link https://nodejs.org/api/http.html#http_event_request|request} @@ -74,14 +74,14 @@ class HttpDuplex extends EventEmitter { } /** - * Request/response headers. Key-value pairs of header names and values. Header names are always lower-case. + * Request/response headers. Key-value pairs of header names and values. Header names are always lower-case. * @name headers * @alias HttpDuplex.headers * @memberof HttpDuplex - * @type {object} + * @type {Object} * @readonly * @see {@link https://nodejs.org/api/http.html#http_message_headers|message.headers} - */ + */ get headers() { return this.req.headers; } @@ -91,7 +91,7 @@ class HttpDuplex extends EventEmitter { * @name httpVersion * @alias HttpDuplex.httpVersion * @memberof HttpDuplex - * @type {string} + * @type {String} * @see {@link https://nodejs.org/api/http.html#http_message_httpversion|message.httpVersion} * @readonly */ @@ -104,7 +104,7 @@ class HttpDuplex extends EventEmitter { * @name httpVersionMajor * @alias HttpDuplex.httpVersionMajor * @memberof HttpDuplex - * @type {number} + * @type {Number} * @see httpVersion * @readonly */ @@ -117,29 +117,29 @@ class HttpDuplex extends EventEmitter { * @name httpVersionMinor * @alias HttpDuplex.httpVersionMinor * @memberof HttpDuplex - * @type {string} + * @type {String} * @see httpVersion * @readonly */ get httpVersionMinor() { return this.req.httpVersionMinor; } - + /** * Request method of the incoming request. - * @type {string} + * @type {String} * @see {@link https://nodejs.org/api/http.html#http_event_request|request} * @see {@link https://nodejs.org/api/http.html#http_class_http_serverresponse|http.ServerResponse} * @example 'GET', 'DELETE' * @readonly - */ + */ get method() { return this.req.method; } /** * Is this stream readable. - * @type {boolean} + * @type {Boolean} * @readonly */ get readable() { @@ -148,7 +148,7 @@ class HttpDuplex extends EventEmitter { /** * net.Socket object associated with the connection. - * @type net.Socket + * @type net.Socket * @see {@link https://nodejs.org/api/net.html#net_class_net_socket|net.Socket} * @readonly */ @@ -157,8 +157,8 @@ class HttpDuplex extends EventEmitter { } /** - * The HTTP status code. Generally assigned before sending headers for a response to a client. - * @type {number} + * The HTTP status code. Generally assigned before sending headers for a response to a client. + * @type {Number} * @default 200 * @see {@link https://nodejs.org/api/http.html#http_response_statuscode|response.statusCode} * @example request.statusCode = 404; @@ -174,7 +174,7 @@ class HttpDuplex extends EventEmitter { /** * Controls the status message sent to the client as long as an explicit call to response.writeHead() isn't made * If ignored or the value is undefined, the default message corresponding to the status code will be used. - * @type {string} + * @type {String} * @default undefined * @see {@link https://nodejs.org/api/http.html#http_response_statusmessage|response.statusMessage} * @example request.statusMessage = 'Document Not found'; @@ -188,12 +188,12 @@ class HttpDuplex extends EventEmitter { } /** - * Request/response trailer headers. Just like {@link headers} except these are only written + * Request/response trailer headers. Just like {@link headers} except these are only written * after the initial response to the client. - * This object is only populated at the 'end' event and only work if a 'transfer-encoding: chunked' + * This object is only populated at the 'end' event and only work if a 'transfer-encoding: chunked' * header is sent in the initial response. * @name HttpDuplex#trailers - * @type {object} + * @type {Object} * @readonly * @see headers * @see addTrailers @@ -206,7 +206,7 @@ class HttpDuplex extends EventEmitter { /** * Whether or not the client connection has been upgraded - * @type {boolean} + * @type {Boolean} * @see {@link https://nodejs.org/api/http.html#http_event_upgrade_1|upgrade} * @readonly */ @@ -218,9 +218,9 @@ class HttpDuplex extends EventEmitter { * Request URL string. * @example A request made as: * GET /info?check=none HTTP/1.1 - * @example Will return the string + * @example Will return the string * '/info?check=none' - * @type {string} + * @type {String} * @readonly */ get url() { @@ -280,14 +280,14 @@ module.exports = HttpDuplex; * passed as a Buffer. * @event data * @alias HttpDuplex#event:data - * @param {(string|buffer|any)} chunk The chunk is either a buffer or string when the stream isn't operating + * @param {(string|buffer|any)} chunk The chunk is either a buffer or string when the stream isn't operating * in object mode. When the stream is in object mode, the chunk can be any JavaScript value other than null. * @memberof HttpDuplex * @see {@link https://nodejs.org/api/stream.html#stream_event_data|stream.Readable/data} */ /** - * If a call to response.write(chunk) returns false, the drain event will be emitted once it is appropriate to + * If a call to response.write(chunk) returns false, the drain event will be emitted once it is appropriate to * resume writing data to the stream. * @event drain * @alias HttpDuplex#event:drain @@ -322,12 +322,12 @@ module.exports = HttpDuplex; /** * Adds trailing headers to the response. - * Trailers will only be emitted if chunked encoding is enabled for the response; otherwise they are discarded. + * Trailers will only be emitted if chunked encoding is enabled for the response; otherwise they are discarded. * @method addTrailers * @name addTrailers * @alias HttpDuplex.addTrailers * @memberof HttpDuplex - * @param {object} headers Trailing headers to add to the response + * @param {Object} headers Trailing headers to add to the response * @see trailers * @see headers * @see {@link https://nodejs.org/api/http.html#http_message_trailers|message.trailers} @@ -357,7 +357,7 @@ module.exports = HttpDuplex; * @alias HttpDuplex.end * @memberof HttpDuplex * @param {(string|Buffer)} data optional data to write to the response before closing the connection - * @param {string} encoding Encoding that should be used to write the data + * @param {String} encoding Encoding that should be used to write the data * @param {function} callback Function to be called once the response stream is finished * @see {@link https://nodejs.org/api/http.html#http_response_end_data_encoding_callback|response.end} */ @@ -367,28 +367,28 @@ module.exports = HttpDuplex; * @method getHeader * @alias HttpDuplex.getHeader * @memberof HttpDuplex - * @param {string} name Header to get the value of - * @returns {string} + * @param {String} name Header to get the value of + * @returns {String} * @see {@link https://nodejs.org/api/http.html#http_request_getheader_name|getHeader} * @example * let contentType = request.getHeader('Content-Type'); */ /** - * Switch readable stream out of flowing mode and stop emitting 'data' events. + * Switch readable stream out of flowing mode and stop emitting 'data' events. * Any new data that becomes available during this time will stay buffered until resume is called. * @method pause * @alias HttpDuplex.pause * @memberof HttpDuplex * @see {@link https://nodejs.org/api/stream.html#stream_readable_pause|stream.Readable.pause} */ - + /** * Remove a header from the response headers. * @method removeHeader * @alias HttpDuplex.removeHeader * @memberof HttpDuplex - * @param {string} name Header to remove + * @param {String} name Header to remove * @see {@link https://nodejs.org/api/http.html#http_request_removeheader_name|removeHeader} * @example * request.removeHeader('Content-Type'); @@ -402,13 +402,13 @@ module.exports = HttpDuplex; * @memberof HttpDuplex * @see {@link https://nodejs.org/api/stream.html#stream_readable_resume|stream.Readable.resume} */ - + /** * Sets the character encoding for data written to the stream. * @method setDefaultEncoding * @alias HttpDuplex.setDefaultEncoding * @memberof HttpDuplex - * @param encoding {string} new character encoding + * @param encoding {String} new character encoding * @see setEncoding * @example request.setDefaultEncoding('utf8'); */ @@ -418,18 +418,18 @@ module.exports = HttpDuplex; * @method setEncoding * @alias HttpDuplex.setEncoding * @memberof HttpDuplex - * @param encoding {string} new character encoding + * @param encoding {String} new character encoding * @see setDefaultEncoding - * @example request.setEncoding('utf8'); + * @example request.setEncoding('utf8'); */ /** - * Set a single header. If the header already exists, it will be replaced. + * Set a single header. If the header already exists, it will be replaced. * It's possible to use an array of strings in place of value to send multiple headers with the same name. * @method setHeader * @alias HttpDuplex.setHeader * @memberof HttpDuplex - * @param {string} name Header to set + * @param {String} name Header to set * @param {string|string[]} value Value(s) to assign to header * @see removeHeader * @see {@link https://nodejs.org/api/http.html#http_request_setheader_name_value|setHeader} @@ -438,7 +438,7 @@ module.exports = HttpDuplex; * @example Array of string value * request.setHeader('Set-Cookie', ['type=auth', 'language=javascript']); */ - + /** * Flushes all data buffered since cork() was called. * @method uncork @@ -454,19 +454,19 @@ module.exports = HttpDuplex; *

                                *Note:* If write() is called either before writeHead() or writeHead() just hasn't been called, it will switch * modes and flush the implicit headers that may be waiting before parts of this chunk are sent.

                                * Node will buffer up to the first chunk of the body. Any additional calls to write() may be buffered as well * for packet efficiency purposes.

                                - * Returns true if the entire data was flushed successfully to the kernel buffer. Returns false if all or part of + * Returns true if the entire data was flushed successfully to the kernel buffer. Returns false if all or part of * the data was buffered in memory. * @method write * @alias HttpDuplex.write * @memberof HttpDuplex * @param {(string|Buffer)} chunk chunk of data to send. - * @param {string} [encoding='utf8'] If chunk is a string, this specifies how to encode it into a byte stream. + * @param {String} [encoding='utf8'] If chunk is a string, this specifies how to encode it into a byte stream. * @param {function} [callback] Callback to call when this chunk of data is flushed. - * @returns {boolean} + * @returns {Boolean} * @emits {@link event:drain|drain} Emitted when data was buffered and the buffer has become free for use again. * @see {@link https://nodejs.org/api/http.html#http_response_write_chunk_encoding_callback|http.ServerResponse.write} */ - + /** * Sends an HTTP/1.1 100 Continue message to the client. * @method writeContinue @@ -481,24 +481,24 @@ module.exports = HttpDuplex; * @method writeHead * @alias HttpDuplex.writeHead * @memberof HttpDuplex - * @param {number} statusCode 3-digit HTTP status code, like 404 - * @param {string} [statusMessage] An optional human readable status message to send with the status code - * @param {object} [headers] An object containing the response headers to send + * @param {Number} statusCode 3-digit HTTP status code, like 404 + * @param {String} [statusMessage] An optional human readable status message to send with the status code + * @param {Object} [headers] An object containing the response headers to send * @see {@link https://nodejs.org/api/http.html#http_response_writehead_statuscode_statusmessage_headers|response.writeHead} * @example var content = 'Under Construction...'; * response.writeHead(200, { * 'Content-Length': Buffer.byteLength(content), - * 'Content-Type': 'text/plain' + * 'Content-Type': 'text/plain' * }); * response.end(content); */ - + /** - * __Warning:__ This has been deprecated in node, __don't__ use it. Any apis that require this funtion should be + * __Warning:__ This has been deprecated in node, __don't__ use it. Any apis that require this funtion should be * updated to use writeHead insted. * @method writeHeader * @alias HttpDuplex.writeHeader - * @memberof HttpDuplex + * @memberof HttpDuplex * @deprecated {@link https://nodejs.org/api/deprecations.html#deprecations_dep0063_serverresponse_prototype_writeheader|Node Deprecated} * @see writeHead */ diff --git a/lib/service.js b/lib/service.js index 2f78245..0f50176 100644 --- a/lib/service.js +++ b/lib/service.js @@ -3,25 +3,21 @@ const HttpDuplex = require('./http-duplex'); const zlib = require('zlib'); const { spawn } = require('child_process'); -const { inherits } = require('util'); - -const encodings = { - 'gzip': () => zlib.createGunzip(), - 'deflate': () => zlib.createDeflate() -}; const headerRE = { - 'receive-pack': '([0-9a-fA-F]+) ([0-9a-fA-F]+)' + - ' refs\/(heads|tags)\/(.*?)( |00|\u0000)' + // eslint-disable-line - '|^(0000)$', - 'upload-pack': '^\\S+ ([0-9a-fA-F]+)' + 'receive-pack': '([0-9a-fA-F]+) ([0-9a-fA-F]+) refs\/(heads|tags)\/(.*?)( |00|\u0000)|^(0000)$', // eslint-disable-line + 'upload-pack': '^\\S+ ([0-9a-fA-F]+)' }; -/** - * @class Service - * @extends HttpDuplex - */ class Service extends HttpDuplex { + /** + * Handles invoking the git-*-pack binaries + * @class Service + * @extends HttpDuplex + * @param {Object} opts - options to bootstrap the service object + * @param {http.IncomingMessage } req - http request object + * @param {http.ServerResponse} res - http response + */ constructor(opts, req, res) { super(req, res); @@ -38,7 +34,11 @@ class Service extends HttpDuplex { // stream needed to receive data after decoding, but before accepting var ts = through(); - var decoder = encodings[req.headers['content-encoding']]; + var decoder = { + 'gzip': () => zlib.createGunzip(), + 'deflate': () => zlib.createDeflate() + }[req.headers['content-encoding']]; + if (decoder) { // data is compressed with gzip or deflate req.pipe(decoder()).pipe(ts).pipe(buffered); @@ -55,7 +55,7 @@ class Service extends HttpDuplex { } } - ts.once('data', function(buf) { + ts.once('data', function onData(buf) { data += buf; var ops = data.match(new RegExp(headerRE[self.service], 'gi')); @@ -94,50 +94,52 @@ class Service extends HttpDuplex { }); }); - self.once('accept', function() { + self.once('accept', function onAccept() { process.nextTick(function() { var cmd = ['git-' + opts.service, '--stateless-rpc', opts.cwd]; var ps = spawn(cmd[0], cmd.slice(1)); ps.on('error', function(err) { - self.emit('error', new Error( - err.message + ' running command ' + cmd.join(' ') - )); + self.emit('error', new Error(`${err.message} running command ${cmd.join(' ')}`)); }); self.emit('service', ps); var respStream = through(function(c) { - if (self.listeners('response').length === 0) - return this.queue(c); + if (self.listeners('response').length === 0) return this.queue(c); // prevent git from sending the close signal - if (c.length === 4 && c.toString() === '0000') - return; + if (c.length === 4 && c.toString() === '0000') return; this.queue(c); }, function() { - if (self.listeners('response').length > 0) - return; + if (self.listeners('response').length > 0) return; this.queue(null); }); - const endResponse = () => { + + self.emit('response', respStream, function endResponse() { res.queue(new Buffer('0000')); res.queue(null); - }; - - self.emit('response', respStream, endResponse); + }); ps.stdout.pipe(respStream).pipe(res); buffered.pipe(ps.stdin); buffered.resume(); + ps.on('exit', self.emit.bind(self, 'exit')); }); }); - self.once('reject', (code, msg) => { + self.once('reject', function onReject(code, msg) { res.statusCode = code; res.end(msg); }); } + /** + * reject request in flight + * @method reject + * @memberof Service + * @param {Number} code - http response code + * @param {String} msg - message that should be displayed on teh client + */ reject(code, msg) { if (this.status !== 'pending') return; @@ -148,14 +150,17 @@ class Service extends HttpDuplex { this.status = 'rejected'; this.emit('reject', code || 500, msg); } - accept(dir) { + /** + * accepts request to access resource + * @method accept + * @memberof Service + */ + accept() { if (this.status !== 'pending') return; this.status = 'accepted'; - this.emit('accept', dir); + this.emit('accept'); } } -inherits(Service, HttpDuplex); - module.exports = Service; diff --git a/lib/util.js b/lib/util.js index cd70cdb..3d187d3 100644 --- a/lib/util.js +++ b/lib/util.js @@ -2,16 +2,16 @@ * @module lib/util */ -const httpDuplex = require('./http-duplex'); const { spawn } = require('child_process'); +const httpDuplex = require('./http-duplex'); const Service = require('./service'); const Util = { /** * adds headers to the response object to add cache control * @method noCache - * @param {Object} res - http response object + * @param {http.ServerResponse} res - http response */ noCache: function noCache(res) { res.setHeader('expires', 'Fri, 01 Jan 1980 00:00:00 GMT'); @@ -21,8 +21,8 @@ const Util = { /** * sets and parses basic auth headers if they exist * @method basicAuth - * @param {Object} req - http request object - * @param {Object} res - http response object + * @param {http.IncomingMessage } req - http request object + * @param {http.ServerResponse} res - http response * @param {Function} callback - function(username, password, error) */ basicAuth: function basicAuth(req, res, callback) { @@ -48,8 +48,9 @@ const Util = { * @param {Function} callback - function(code, signature) */ onExit: function onExit(ps, callback) { - var code, sig; - var pending = 3; + let code; + let sig; + let pending = 3; const onend = () => { if (--pending === 0) { @@ -66,7 +67,15 @@ const Util = { ps.stdout.on('end', onend); ps.stderr.on('end', onend); }, - serviceRespond: function serviceRespond(self, service, file, res) { + /** + * execute given git operation and respond + * @method serviceRespond + * @param {HttpDuplex} dup - duplex object to catch errors + * @param {String} service - the method that is responding infoResponse (push, pull, clone) + * @param {String} repoLocation - the repo path on disk + * @param {http.ServerResponse} res - http response + */ + serviceRespond: function serviceRespond(dup, service, repoLocation, res) { const pack = (s) => { var n = (4 + s.length).toString(16); return Array(4 - n.length + 1).join('0') + n + s; @@ -75,20 +84,26 @@ const Util = { res.write(pack('# service=git-' + service + '\n')); res.write('0000'); - const cmd = ['git-' + service, '--stateless-rpc', '--advertise-refs', file]; + const cmd = ['git-' + service, '--stateless-rpc', '--advertise-refs', repoLocation]; const ps = spawn(cmd[0], cmd.slice(1)); ps.on('error', (err) => { - self.emit('error', new Error( - err.message + ' running command ' + cmd.join(' ') - )); + dup.emit('error', new Error(`${err.message} running command ${cmd.join(' ')}`)); }); ps.stdout.pipe(res); }, - infoResponse: function infoResponse(opts, req, res) { - var self = opts.repos; + /** + * sends http response using the appropriate output from service call + * @method infoResponse + * @param {Git} git - an instance of git object + * @param {String} repo - the repository + * @param {String} service - the method that is responding infoResponse (push, pull, clone) + * @param {http.IncomingMessage } req - http request object + * @param {http.ServerResponse} res - http response + */ + infoResponse: function infoResponse(git, repo, service, req, res) { var dup = new httpDuplex(req, res); - dup.cwd = self.dirMap(opts.repo); - dup.repo = opts.repo; + dup.cwd = git.dirMap(repo); + dup.repo = repo; dup.accept = dup.emit.bind(dup, 'accept'); dup.reject = dup.emit.bind(dup, 'reject'); @@ -98,17 +113,17 @@ const Util = { res.end(); }); - var anyListeners = self.listeners('info').length > 0; + var anyListeners = git.listeners('info').length > 0; - self.exists(opts.repo, (ex) => { + git.exists(repo, (ex) => { dup.exists = ex; - if (!ex && self.autoCreate) { + if (!ex && git.autoCreate) { dup.once('accept', () => { - self.create(opts.repo, next); + git.create(repo, next); }); - self.emit('info', dup); + git.emit('info', dup); if (!anyListeners) dup.accept(); } else if (!ex) { res.statusCode = 404; @@ -116,7 +131,7 @@ const Util = { res.end('repository not found'); } else { dup.once('accept', next); - self.emit('info', dup); + git.emit('info', dup); if (!anyListeners) dup.accept(); } @@ -125,18 +140,22 @@ const Util = { function next() { res.setHeader( 'content-type', - 'application/x-git-' + opts.service + '-advertisement' + 'application/x-git-' + service + '-advertisement' ); Util.noCache(res); - var d = self.dirMap(opts.repo); - Util.serviceRespond(self, opts.service, d, res); + Util.serviceRespond( + git, + service, + git.dirMap(repo), + res + ); } }, /** * parses a git string and returns the repo name * @method parseGitName * @param {String} repo - the raw repo name containing .git - * @return {String} - returns the name of the repo + * @return {String} returns the name of the repo */ parseGitName: function parseGitName(repo) { const locationOfGit = repo.lastIndexOf('.git'); @@ -146,8 +165,8 @@ const Util = { * responds with the correct service depending on the action * @method createAction * @param {Object} opts - options to pass Service - * @param {Object} req - http request object - * @param {Object} res - http response object + * @param {http.IncomingMessage } req - http request object + * @param {http.ServerResponse} res - http response * @return {Service} */ createAction: function createAction(opts, req, res) { diff --git a/test/httpduplex.js b/test/http-duplex.js similarity index 93% rename from test/httpduplex.js rename to test/http-duplex.js index 94b6b4e..542a8cb 100644 --- a/test/httpduplex.js +++ b/test/http-duplex.js @@ -11,11 +11,11 @@ Object.prototype.serialize = function() { Object.prototype.filterKeys = function(key) { var obj = this; - Object.keys(this).forEach(function (i) { + Object.keys(this).forEach(function (i) { if (i == key) delete obj[i]; }); - + return obj; }; @@ -52,7 +52,7 @@ var server = http.createServer(function (req, res) { dup.end(size + '\n'); }); } - else fs.createReadStream(__filename).pipe(dup); + else fs.createReadStream(__filename).pipe(dup); break; case '/info': if (dup.method == 'GET') { @@ -73,7 +73,7 @@ var server = http.createServer(function (req, res) { "Client: {12}\n" + "Socket: {13}\n" ).format ( - dup.method, + dup.method, dup.url, dup.statusCode, dup.upgrade, @@ -101,7 +101,7 @@ var server = http.createServer(function (req, res) { } }); -test(function (t) { +test('http-duplex', (t) => { t.plan(3); server.listen(0); @@ -126,16 +126,16 @@ test(function (t) { "Status: 200\n" + "Upgrade: false\n" + "Http Version 1: 1.1\n" + - "Http Version 2: 1.1\n" + + "Http Version 2: 1.1\n" + "Headers: \n" + "{\n" + " \"host\": \"localhost:" + server.address().port + "\",\n" + " \"connection\": \"close\"\n" + - "}\n" + + "}\n" + "Trailers: {}\n" + - "Complete: false\n" + + "Complete: false\n" + "Readable: true\n" + - "Writeable: {10}\n" + + "Writeable: {10}\n" + "Connection: [object Object]\n" + "Client: [object Object]\n" + "Socket: [object Object]\n"; From faad289b2acbd36df32ef39cc8bd9604e91bd710 Mon Sep 17 00:00:00 2001 From: echopoint <32996843+echopoint@users.noreply.github.com> Date: Fri, 10 Nov 2017 22:28:09 +0000 Subject: [PATCH 02/14] updates duplex lib to fix cork,uncork and change the behavior of writeHead slightly. These three methods are now chainable. (#27) --- lib/http-duplex.js | 97 ++++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 41 deletions(-) diff --git a/lib/http-duplex.js b/lib/http-duplex.js index 7cea0a1..aacb9d3 100644 --- a/lib/http-duplex.js +++ b/lib/http-duplex.js @@ -231,6 +231,61 @@ class HttpDuplex extends EventEmitter { get writable() { return this.res.writable; } + + /** + * Sends a response header to the client request. Must only be called one time and before calling response.end(). + * @method writeHead + * @alias HttpDuplex.writeHead + * @memberof HttpDuplex + * @param {number} statusCode 3-digit HTTP status code, like 404 + * @param {string} [statusMessage] An optional human readable status message to send with the status code + * @param {object} [headers] An object containing the response headers to send + * @returns {this} + * @see {@link https://nodejs.org/api/http.html#http_response_writehead_statuscode_statusmessage_headers|response.writeHead} + * @example var content = 'Under Construction...'; + * response.writeHead(200, { + * 'Content-Length': Buffer.byteLength(content), + * 'Content-Type': 'text/plain' + * }); + * response.end(content); + */ + writeHead(statusCode, statusMessage, headers) { + this.res.writeHead(statusCode, statusMessage, headers); + return this; + } + + /** + * Buffers written data in memory. This data will be flushed when either the uncork or end methods are called. + * @method cork + * @alias HttpDuplex.cork + * @memberof HttpDuplex + * @returns {this} + * @see uncork + * @see {@link https://nodejs.org/api/stream.html#stream_writable_cork|stream.Writeable.cork} + * @example + * request.cork(); + * request.write('buffer data '); + * request.write('before sending '); + * request.uncork(); + */ + cork() { + this.res.connection.cork(); + return this; + } + + /** + * Flushes all data buffered since cork() was called. + * @method uncork + * @alias HttpDuplex.cork + * @memberof HttpDuplex + * @returns {this} + * @see cork + * @see {@link https://nodejs.org/api/stream.html#stream_writable_uncork|stream.Writeable.uncork} + */ + uncork() { + this.res.connection.uncork(); + return this; + } } // proxy request methods @@ -242,7 +297,7 @@ class HttpDuplex extends EventEmitter { // proxy respone methods [ - 'cork', 'uncork', 'setDefaultEncoding', 'write', 'end', 'flush', 'writeHeader', 'writeHead', 'writeContinue', + 'setDefaultEncoding', 'write', 'end', 'flush', 'writeHeader', 'writeContinue', 'setHeader', 'getHeader', 'removeHeader', 'addTrailers' ].forEach(function (name) { HttpDuplex.prototype[name] = function () { @@ -334,20 +389,6 @@ module.exports = HttpDuplex; * @see {@link https://nodejs.org/api/http.html#http_response_addtrailers_headers|response.addTrailers} */ -/** - * Buffers written data in memory. This data will be flushed when either the uncork or end methods are called. - * @method cork - * @alias HttpDuplex.cork - * @memberof HttpDuplex - * @see uncork - * @see {@link https://nodejs.org/api/stream.html#stream_writable_cork|stream.Writeable.cork} - * @example - * request.cork(); - * request.write('buffer data '); - * request.write('before sending '); - * request.uncork(); - */ - /** * Tells the server the response headers and body have been sent and that the message should be considered complete. * This MUST be called on every response. @@ -439,15 +480,6 @@ module.exports = HttpDuplex; * request.setHeader('Set-Cookie', ['type=auth', 'language=javascript']); */ -/** - * Flushes all data buffered since cork() was called. - * @method uncork - * @alias HttpDuplex.cork - * @memberof HttpDuplex - * @see cork - * @see {@link https://nodejs.org/api/stream.html#stream_writable_uncork|stream.Writeable.uncork} - */ - /** * Sends a chunk of the response body. This method may be called multiple times to provide successive parts of the * body. @@ -476,23 +508,6 @@ module.exports = HttpDuplex; * {@link https://nodejs.org/api/http.html#http_event_checkcontinue|http.Server/checkContinue} */ -/** - * Sends a response header to the client request. Must only be called one time and before calling response.end(). - * @method writeHead - * @alias HttpDuplex.writeHead - * @memberof HttpDuplex - * @param {Number} statusCode 3-digit HTTP status code, like 404 - * @param {String} [statusMessage] An optional human readable status message to send with the status code - * @param {Object} [headers] An object containing the response headers to send - * @see {@link https://nodejs.org/api/http.html#http_response_writehead_statuscode_statusmessage_headers|response.writeHead} - * @example var content = 'Under Construction...'; - * response.writeHead(200, { - * 'Content-Length': Buffer.byteLength(content), - * 'Content-Type': 'text/plain' - * }); - * response.end(content); - */ - /** * __Warning:__ This has been deprecated in node, __don't__ use it. Any apis that require this funtion should be * updated to use writeHead insted. From d9aabdfb8405e3cc6c84e30f6960e38f83dd8d9b Mon Sep 17 00:00:00 2001 From: Gabriel Csapo Date: Fri, 10 Nov 2017 14:29:50 -0800 Subject: [PATCH 03/14] 0.3.4 - updates duplex lib to fix cork, uncork and add some chaining - adds extensive docs to Git, Util and Service - adds named function to events to trace errors more easily --- CHANGELOG.md | 3 +- docs/code/Git.html | 4 +- docs/code/HttpDuplex.html | 110 +++++++++++++++++++++++++--------- docs/code/http-duplex.js.html | 97 +++++++++++++++++------------- package.json | 2 +- 5 files changed, 143 insertions(+), 73 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3ef6d8..8d8e1ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ -# Unreleased +# 0.3.4 (11/10/2017) +- updates duplex lib to fix cork, uncork and add some chaining - adds extensive docs to Git, Util and Service - adds named function to events to trace errors more easily diff --git a/docs/code/Git.html b/docs/code/Git.html index 68653ba..657d147 100644 --- a/docs/code/Git.html +++ b/docs/code/Git.html @@ -1882,7 +1882,7 @@

                                info

                                Source:
                                @@ -2082,7 +2082,7 @@

                                info

                                Source:
                                diff --git a/docs/code/HttpDuplex.html b/docs/code/HttpDuplex.html index 3bc0df1..11cba24 100644 --- a/docs/code/HttpDuplex.html +++ b/docs/code/HttpDuplex.html @@ -1528,7 +1528,7 @@

                                addTrailer
                                Source:
                                @@ -1663,7 +1663,7 @@

                                Parameters:
                                -

                                cork()

                                +

                                cork() → {this}

                                @@ -1675,7 +1675,7 @@

                                corkSource:
                                @@ -1757,6 +1757,24 @@
                                Example
                                +
                                Returns:
                                + + + + +
                                +
                                + Type +
                                +
                                + +this + + +
                                +
                                + + @@ -1776,7 +1794,7 @@

                                destroySource:
                                @@ -1860,7 +1878,7 @@

                                endSource:
                                @@ -2052,7 +2070,7 @@

                                getHeaderSource:
                                @@ -2215,7 +2233,7 @@

                                pauseSource:
                                @@ -2307,7 +2325,7 @@

                                removeHea
                                Source:
                                @@ -2452,7 +2470,7 @@

                                resumeSource:
                                @@ -2544,7 +2562,7 @@

                                set
                                Source:
                                @@ -2689,7 +2707,7 @@

                                setEncodin
                                Source:
                                @@ -2834,7 +2852,7 @@

                                setHeaderSource:
                                @@ -3002,7 +3020,7 @@
                                Parameters:
                                -

                                uncork()

                                +

                                uncork() → {this}

                                @@ -3014,7 +3032,7 @@

                                uncorkSource:
                                @@ -3088,6 +3106,24 @@

                                uncorkReturns:

                                + + + + +
                                +
                                + Type +
                                +
                                + +this + + +
                                +
                                + + @@ -3107,7 +3143,7 @@

                                writeSource:
                                @@ -3371,7 +3407,7 @@

                                writeCon
                                Source:
                                @@ -3451,7 +3487,7 @@

                                writeCon -

                                writeHead(statusCode, statusMessageopt, headersopt)

                                +

                                writeHead(statusCode, statusMessageopt, headersopt) → {this}

                                @@ -3463,7 +3499,7 @@

                                writeHeadSource:
                                @@ -3526,7 +3562,7 @@
                                Example
                                var content = 'Under Construction...';
                                 response.writeHead(200, {
                                     'Content-Length': Buffer.byteLength(content),
                                -    'Content-Type': 'text/plain'
                                +    'Content-Type': 'text/plain' 
                                 });
                                 response.end(content);
                                @@ -3566,7 +3602,7 @@
                                Parameters:
                                -Number +number @@ -3597,7 +3633,7 @@
                                Parameters:
                                -String +string @@ -3630,7 +3666,7 @@
                                Parameters:
                                -Object +object @@ -3670,6 +3706,24 @@
                                Parameters:
                                +
                                Returns:
                                + + + + +
                                +
                                + Type +
                                +
                                + +this + + +
                                +
                                + + @@ -3689,7 +3743,7 @@

                                writeHeade
                                Source:
                                @@ -3791,7 +3845,7 @@

                                close

                                Source:
                                @@ -3884,7 +3938,7 @@

                                data

                                Source:
                                @@ -4035,7 +4089,7 @@

                                drain

                                Source:
                                @@ -4127,7 +4181,7 @@

                                end

                                Source:
                                @@ -4219,7 +4273,7 @@

                                error

                                Source:
                                diff --git a/docs/code/http-duplex.js.html b/docs/code/http-duplex.js.html index c0e7423..c571ed9 100644 --- a/docs/code/http-duplex.js.html +++ b/docs/code/http-duplex.js.html @@ -270,6 +270,61 @@

                                http-duplex.js

                                get writable() { return this.res.writable; } + + /** + * Sends a response header to the client request. Must only be called one time and before calling response.end(). + * @method writeHead + * @alias HttpDuplex.writeHead + * @memberof HttpDuplex + * @param {number} statusCode 3-digit HTTP status code, like 404 + * @param {string} [statusMessage] An optional human readable status message to send with the status code + * @param {object} [headers] An object containing the response headers to send + * @returns {this} + * @see {@link https://nodejs.org/api/http.html#http_response_writehead_statuscode_statusmessage_headers|response.writeHead} + * @example var content = 'Under Construction...'; + * response.writeHead(200, { + * 'Content-Length': Buffer.byteLength(content), + * 'Content-Type': 'text/plain' + * }); + * response.end(content); + */ + writeHead(statusCode, statusMessage, headers) { + this.res.writeHead(statusCode, statusMessage, headers); + return this; + } + + /** + * Buffers written data in memory. This data will be flushed when either the uncork or end methods are called. + * @method cork + * @alias HttpDuplex.cork + * @memberof HttpDuplex + * @returns {this} + * @see uncork + * @see {@link https://nodejs.org/api/stream.html#stream_writable_cork|stream.Writeable.cork} + * @example + * request.cork(); + * request.write('buffer data '); + * request.write('before sending '); + * request.uncork(); + */ + cork() { + this.res.connection.cork(); + return this; + } + + /** + * Flushes all data buffered since cork() was called. + * @method uncork + * @alias HttpDuplex.cork + * @memberof HttpDuplex + * @returns {this} + * @see cork + * @see {@link https://nodejs.org/api/stream.html#stream_writable_uncork|stream.Writeable.uncork} + */ + uncork() { + this.res.connection.uncork(); + return this; + } } // proxy request methods @@ -281,7 +336,7 @@

                                http-duplex.js

                                // proxy respone methods [ - 'cork', 'uncork', 'setDefaultEncoding', 'write', 'end', 'flush', 'writeHeader', 'writeHead', 'writeContinue', + 'setDefaultEncoding', 'write', 'end', 'flush', 'writeHeader', 'writeContinue', 'setHeader', 'getHeader', 'removeHeader', 'addTrailers' ].forEach(function (name) { HttpDuplex.prototype[name] = function () { @@ -373,20 +428,6 @@

                                http-duplex.js

                                * @see {@link https://nodejs.org/api/http.html#http_response_addtrailers_headers|response.addTrailers} */ -/** - * Buffers written data in memory. This data will be flushed when either the uncork or end methods are called. - * @method cork - * @alias HttpDuplex.cork - * @memberof HttpDuplex - * @see uncork - * @see {@link https://nodejs.org/api/stream.html#stream_writable_cork|stream.Writeable.cork} - * @example - * request.cork(); - * request.write('buffer data '); - * request.write('before sending '); - * request.uncork(); - */ - /** * Tells the server the response headers and body have been sent and that the message should be considered complete. * This MUST be called on every response. @@ -478,15 +519,6 @@

                                http-duplex.js

                                * request.setHeader('Set-Cookie', ['type=auth', 'language=javascript']); */ -/** - * Flushes all data buffered since cork() was called. - * @method uncork - * @alias HttpDuplex.cork - * @memberof HttpDuplex - * @see cork - * @see {@link https://nodejs.org/api/stream.html#stream_writable_uncork|stream.Writeable.uncork} - */ - /** * Sends a chunk of the response body. This method may be called multiple times to provide successive parts of the * body. @@ -515,23 +547,6 @@

                                http-duplex.js

                                * {@link https://nodejs.org/api/http.html#http_event_checkcontinue|http.Server/checkContinue} */ -/** - * Sends a response header to the client request. Must only be called one time and before calling response.end(). - * @method writeHead - * @alias HttpDuplex.writeHead - * @memberof HttpDuplex - * @param {Number} statusCode 3-digit HTTP status code, like 404 - * @param {String} [statusMessage] An optional human readable status message to send with the status code - * @param {Object} [headers] An object containing the response headers to send - * @see {@link https://nodejs.org/api/http.html#http_response_writehead_statuscode_statusmessage_headers|response.writeHead} - * @example var content = 'Under Construction...'; - * response.writeHead(200, { - * 'Content-Length': Buffer.byteLength(content), - * 'Content-Type': 'text/plain' - * }); - * response.end(content); - */ - /** * __Warning:__ This has been deprecated in node, __don't__ use it. Any apis that require this funtion should be * updated to use writeHead insted. diff --git a/package.json b/package.json index 1673c4e..0b41629 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-git-server", - "version": "0.3.3", + "version": "0.3.4", "description": "🎡 A configurable git server written in Node.js", "author": "Gabriel J. Csapo ", "contributors": [ From 6d80414f3d8736cf7bfb3a5bd41001f73b649d09 Mon Sep 17 00:00:00 2001 From: Gabriel Csapo Date: Thu, 23 Nov 2017 20:39:38 -0800 Subject: [PATCH 04/14] updates docs page --- docs/index.html | 6 +----- package.json | 10 +++++----- tryitout.js | 4 +++- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/index.html b/docs/index.html index 96ab97d..486061a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -8,9 +8,5 @@
                                - + diff --git a/package.json b/package.json index 0b41629..0c6d386 100644 --- a/package.json +++ b/package.json @@ -26,18 +26,18 @@ "lint": "eslint .", "test": "tape test/*.js", "coverage": "tap test/*.js --coverage --coverage-report=lcov", - "generate-docs": "tryitout --template=landing --output=./docs && jsdoc -c jsdoc.json" + "generate-docs": "tryitout && jsdoc -c jsdoc.json" }, "dependencies": { "through": "^2.3.8" }, "devDependencies": { - "async": "^2.5.0", + "async": "^2.6.0", "docdash": "^0.4.0", - "eslint": "^4.10.0", + "eslint": "^4.11.0", "jsdoc": "^3.5.5", - "tap": "^10.7.2", + "tap": "^10.7.3", "tape": "^4.8.0", - "tryitout": "^1.0.0" + "tryitout": "^1.2.0" } } diff --git a/tryitout.js b/tryitout.js index 707a7f6..9a7d639 100644 --- a/tryitout.js +++ b/tryitout.js @@ -31,5 +31,7 @@ module.exports = { }, footer: `
                                Made with ☕️ by @gabrielcsapo
                                - ` + `, + template: 'landing', + output: './docs' }; From 0961dacd37ce8b4514a8f2bbcb6811b43379e8f3 Mon Sep 17 00:00:00 2001 From: Gabriel Csapo Date: Sun, 3 Dec 2017 17:41:52 -0800 Subject: [PATCH 05/14] makes authenticate more flexible (#30) * makes authenticate more flexible - [BREAKING] changes the interface for authentication to make it more flexible - when error is sent back to client ensure error is string * updates readme and example * adds README notice --- CHANGELOG.md | 5 + README.md | 16 +- docs/code/Git.html | 12 +- docs/code/HttpDuplex.html | 2 +- docs/code/Service.html | 2 +- docs/code/git.js.html | 36 ++-- docs/code/global.html | 294 +++++++++++++++++++++++++++++++++ docs/code/http-duplex.js.html | 2 +- docs/code/index.html | 14 +- docs/code/module-lib_util.html | 2 +- docs/code/service.js.html | 2 +- docs/code/util.js.html | 2 +- example/index.js | 25 ++- lib/git.js | 34 ++-- test/git.js | 32 +++- 15 files changed, 421 insertions(+), 59 deletions(-) create mode 100644 docs/code/global.html diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d8e1ef..95e0201 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# Unreleased + +- [BREAKING] changes the interface for authentication to make it more flexible +- when error is sent back to client ensure error is string + # 0.3.4 (11/10/2017) - updates duplex lib to fix cork, uncork and add some chaining diff --git a/README.md b/README.md index 3a86497..d65ba3a 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ > 🎡 A configurable git server written in Node.js +>> there be 🐲 here! The API's and functionality are still be cemented, anything before a 1.0.0 release will be subject to change. + [![Npm Version](https://img.shields.io/npm/v/node-git-server.svg)](https://www.npmjs.com/package/node-git-server) [![Build Status](https://travis-ci.org/gabrielcsapo/node-git-server.svg?branch=master)](https://travis-ci.org/gabrielcsapo/node-git-server) [![Coverage Status](https://lcov-server.gabrielcsapo.com/badge/github%2Ecom/gabrielcsapo/node-git-server.svg)](https://lcov-server.gabrielcsapo.com/coverage/github%2Ecom/gabrielcsapo/node-git-server) @@ -20,11 +22,17 @@ npm install node-git-server ```javascript const Server = require('node-git-server'); -const repo = new Server(path.resolve(__dirname, 'tmp'), { +const repos = new Server(path.resolve(__dirname, 'tmp'), { autoCreate: true, - authenticate: (type, repo, username, password, next) => { - console.log(type, repo, username, password); - next(); + authenticate: (type, repo, user, next) => { + if(type == 'upload') { + user((username, password) => { + console.log(username, password); + next(); + }); + } else { + next(); + } } }); const port = process.env.PORT || 7005; diff --git a/docs/code/Git.html b/docs/code/Git.html index 657d147..181a857 100644 --- a/docs/code/Git.html +++ b/docs/code/Git.html @@ -22,7 +22,7 @@
                                @@ -393,7 +393,7 @@

                                (static) close<
                                Source:
                                @@ -829,7 +829,7 @@

                                (static) handl
                                Source:
                                @@ -1118,7 +1118,7 @@

                                (static) liste
                                Source:
                                @@ -1882,7 +1882,7 @@

                                info

                                Source:
                                @@ -2082,7 +2082,7 @@

                                info

                                Source:
                                diff --git a/docs/code/HttpDuplex.html b/docs/code/HttpDuplex.html index 11cba24..0aa4144 100644 --- a/docs/code/HttpDuplex.html +++ b/docs/code/HttpDuplex.html @@ -22,7 +22,7 @@
                                diff --git a/docs/code/Service.html b/docs/code/Service.html index 66552ea..2c2603e 100644 --- a/docs/code/Service.html +++ b/docs/code/Service.html @@ -22,7 +22,7 @@
                                diff --git a/docs/code/git.js.html b/docs/code/git.js.html index c5abe24..aa515c1 100644 --- a/docs/code/git.js.html +++ b/docs/code/git.js.html @@ -22,7 +22,7 @@
                                @@ -275,6 +275,21 @@

                                git.js

                                }); } } + /** + * returns the typeof service being process + * @method getType + * @param {Service} service - the service type + * @return {String} - will respond with either upload or download + */ + getType(service) { + switch(service) { + case 'upload-pack': + case 'receive-pack': + return 'upload'; + default: + return 'download'; + } + } /** * Handle incoming HTTP requests with a connect-style middleware * @method handle @@ -314,7 +329,7 @@

                                git.js

                                res.setHeader("Content-Type", 'text/plain'); res.setHeader("WWW-Authenticate", 'Basic realm="authorization needed"'); res.writeHead(401); - res.end(error); + res.end(typeof error === 'string' ? error : error.toString()); return; } else { return infoResponse(self, repo, service, req, res); @@ -323,16 +338,15 @@

                                git.js

                                // check if the repo is authenticated if(this.authenticate) { - basicAuth(req, res, (username, password) => { - var promise = this.authenticate(service === 'upload-pack' ? 'upload' : 'download', repoName, username, password, (error) => { - return next(error); - }); - if(promise instanceof Promise) { - return promise - .then(next) - .catch(next); - } + const type = this.getType(service); + const promise = this.authenticate(type, repoName, basicAuth.bind(null, req, res), (error) => { + return next(error); }); + if(promise instanceof Promise) { + return promise + .then(next) + .catch(next); + } } else { return next(); } diff --git a/docs/code/global.html b/docs/code/global.html new file mode 100644 index 0000000..669d106 --- /dev/null +++ b/docs/code/global.html @@ -0,0 +1,294 @@ + + + + + Global - Documentation + + + + + + + + + + + + + + + + +
                                + +

                                Global

                                + + + + + + + +
                                + +
                                + +

                                + +

                                + + +
                                + +
                                +
                                + + + +
                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                + + + + + + + + +
                                + + + + + + + + + + + + + + +

                                Methods

                                + + + + + + +

                                getType(service) → {String}

                                + + + + + + +
                                + + +
                                Source:
                                +
                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                + + + + + +
                                +

                                returns the typeof service being process

                                +
                                + + + + + + + + + + + +
                                Parameters:
                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                NameTypeDescription
                                service + + +Service + + + +

                                the service type

                                + + + + + + + + + + + + + + +
                                Returns:
                                + + +
                                +
                                  +
                                • will respond with either upload or download
                                • +
                                +
                                + + + +
                                +
                                + Type +
                                +
                                + +String + + +
                                +
                                + + + + + + + + + + +
                                + +
                                + + + + +
                                + +
                                + + + + + + + \ No newline at end of file diff --git a/docs/code/http-duplex.js.html b/docs/code/http-duplex.js.html index c571ed9..c6e7816 100644 --- a/docs/code/http-duplex.js.html +++ b/docs/code/http-duplex.js.html @@ -22,7 +22,7 @@

                                npm install node-git-server

                                Usage

                                const Server = require('node-git-server');
                                 const repo = new Server(path.resolve(__dirname, 'tmp'), {
                                     autoCreate: true,
                                -    authenticate: (type, repo, username, password, next) => {
                                -      console.log(type, repo, username, password);
                                -      next();
                                +    authenticate: (type, repo, user, next) => {
                                +      if(type == 'upload') {
                                +        user((username, password) => {
                                +          console.log(username, password);
                                +          next();
                                +        });
                                +      } else {
                                +        next();
                                +      }
                                     }
                                 });
                                 const port = process.env.PORT || 7005;
                                diff --git a/docs/code/module-lib_util.html b/docs/code/module-lib_util.html
                                index f97013f..19d87f7 100644
                                --- a/docs/code/module-lib_util.html
                                +++ b/docs/code/module-lib_util.html
                                @@ -22,7 +22,7 @@
                                 
                                 
                                 
                                 
                                 
                                diff --git a/docs/code/service.js.html b/docs/code/service.js.html index e293e33..f6073fd 100644 --- a/docs/code/service.js.html +++ b/docs/code/service.js.html @@ -22,7 +22,7 @@
                                diff --git a/docs/code/util.js.html b/docs/code/util.js.html index fe4bd43..458281a 100644 --- a/docs/code/util.js.html +++ b/docs/code/util.js.html @@ -22,7 +22,7 @@
                                diff --git a/example/index.js b/example/index.js index 38e3ec8..8b43258 100644 --- a/example/index.js +++ b/example/index.js @@ -4,32 +4,39 @@ const Server = require('../'); const port = process.env.PORT || 7005; -const git = new Server(path.normalize(path.resolve(__dirname, 'tmp')), { +const repos = new Server(path.normalize(path.resolve(__dirname, 'tmp')), { autoCreate: true, - authenticate: (type, repo, username, password, next) => { - console.log(type, repo, username, password); // eslint-disable-line - next(); + authenticate: (type, repo, user, next) => { + console.log(type, repo); // eslint-disable-line + if(type == 'upload') { + user((username, password) => { + console.log(username, password); // eslint-disable-line + next(); + }); + } else { + next(); + } } }); -git.on('push', (push) => { +repos.on('push', (push) => { console.log(`push ${push.repo} / ${push.commit} ( ${push.branch} )`); // eslint-disable-line - git.list((err, result) => { + repos.list((err, result) => { console.log(result); // eslint-disable-line }); push.accept(); }); -git.on('fetch', (fetch) => { +repos.on('fetch', (fetch) => { console.log('username', fetch.username); // eslint-disable-line console.log('fetch ' + fetch.repo + '/' + fetch.commit); // eslint-disable-line fetch.accept(); }); -git.listen(port, (error) => { +repos.listen(port, (error) => { if(error) return console.error(`failed to start git-server because of error ${error}`); // eslint-disable-line console.log(`node-git-server running at http://localhost:${port}`); // eslint-disable-line - git.list((err, result) => { + repos.list((err, result) => { if (!result) { console.log("No repositories available..."); // eslint-disable-line } else { diff --git a/lib/git.js b/lib/git.js index 7367544..a9939af 100644 --- a/lib/git.js +++ b/lib/git.js @@ -236,6 +236,21 @@ class Git extends EventEmitter { }); } } + /** + * returns the typeof service being process + * @method getType + * @param {Service} service - the service type + * @return {String} - will respond with either upload or download + */ + getType(service) { + switch(service) { + case 'upload-pack': + case 'receive-pack': + return 'upload'; + default: + return 'download'; + } + } /** * Handle incoming HTTP requests with a connect-style middleware * @method handle @@ -275,7 +290,7 @@ class Git extends EventEmitter { res.setHeader("Content-Type", 'text/plain'); res.setHeader("WWW-Authenticate", 'Basic realm="authorization needed"'); res.writeHead(401); - res.end(error); + res.end(typeof error === 'string' ? error : error.toString()); return; } else { return infoResponse(self, repo, service, req, res); @@ -284,16 +299,15 @@ class Git extends EventEmitter { // check if the repo is authenticated if(this.authenticate) { - basicAuth(req, res, (username, password) => { - var promise = this.authenticate(service === 'upload-pack' ? 'upload' : 'download', repoName, username, password, (error) => { - return next(error); - }); - if(promise instanceof Promise) { - return promise - .then(next) - .catch(next); - } + const type = this.getType(service); + const promise = this.authenticate(type, repoName, basicAuth.bind(null, req, res), (error) => { + return next(error); }); + if(promise instanceof Promise) { + return promise + .then(next) + .catch(next); + } } else { return next(); } diff --git a/test/git.js b/test/git.js index 0dcb424..7294834 100644 --- a/test/git.js +++ b/test/git.js @@ -548,13 +548,13 @@ test('git', (t) => { }); }, (callback) => { - const glog = _spawn('git', [ 'log', '--all'], { cwd : repoDir + '/doom.git' }); + const glog = _spawn('git', [ 'log'], { cwd : repoDir + '/doom.git' }); glog.on('exit', (code) => { t.equal(code, 128); callback(); }); var data = ''; - glog.stderr.on('data', (buf) => data += buf ); + glog.stderr.on('data', (buf) => data += buf); glog.stderr.on('end', () => { const res = /fatal: bad default revision 'HEAD'/.test(data) || /fatal: your current branch 'master' does not have any commits yet/.test(data); t.ok(res); @@ -621,9 +621,16 @@ test('git', (t) => { const repos = new GitServer(repoDir, { autoCreate: true, - authenticate: (type, repo, username, password, next) => { - if(type == 'download', repo == 'doom' && username == 'root' && password == 'root') { - next(); + authenticate: (type, repo, user, next) => { + + if(type == 'download', repo == 'doom') { + user((username, password) => { + if(username == 'root' && password == 'root') { + next(); + } else { + next('that is not the correct password'); + } + }); } else { next('that is not the correct password'); } @@ -677,12 +684,19 @@ test('git', (t) => { const repos = new GitServer(repoDir, { autoCreate: true, - authenticate: (type, repo, username, password) => { + authenticate: (type, repo, user) => { return new Promise(function(resolve, reject) { - if(type == 'download', repo == 'doom' && username == 'root' && password == 'root') { - return resolve(); + if(type == 'download', repo == 'doom') { + user((username, password) => { + if(username == 'root' && password == 'root') { + return resolve(); + } else { + return reject('that is not the correct password'); + } + }); + } else { + return reject('that is not the correct password'); } - return reject('that is not the correct password'); }); } }); From abd8fa4a72b69dc6ecdbe617355155809328d008 Mon Sep 17 00:00:00 2001 From: Gabriel Csapo Date: Sun, 3 Dec 2017 17:43:29 -0800 Subject: [PATCH 06/14] 0.4.0 - [BREAKING] changes the interface for authentication to make it more flexible - when error is sent back to client ensure error is string --- CHANGELOG.md | 2 +- docs/code/index.html | 5 ++++- package.json | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95e0201..165455e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# Unreleased +# 0.4.0 (12/03/2017) - [BREAKING] changes the interface for authentication to make it more flexible - when error is sent back to client ensure error is string diff --git a/docs/code/index.html b/docs/code/index.html index 50c9e5e..34fb666 100644 --- a/docs/code/index.html +++ b/docs/code/index.html @@ -48,6 +48,9 @@

                                Home

                                Classes

                                • node-git-server

                                  🎡 A configurable git server written in Node.js

                                  +
                                  +

                                  there be 🐲 here! The API's and functionality are still be cemented, anything before a 1.0.0 release will be subject to change.

                                  +

                                  Npm Version Build Status @@ -57,7 +60,7 @@

                                  Home

                                  Classes

                                  • npm npm

                                    Install

                                    npm install node-git-server

                                    Usage

                                    const Server = require('node-git-server');
                                    -const repo = new Server(path.resolve(__dirname, 'tmp'), {
                                    +const repos = new Server(path.resolve(__dirname, 'tmp'), {
                                         autoCreate: true,
                                         authenticate: (type, repo, user, next) => {
                                           if(type == 'upload') {
                                    diff --git a/package.json b/package.json
                                    index 0c6d386..b6a80b1 100644
                                    --- a/package.json
                                    +++ b/package.json
                                    @@ -1,6 +1,6 @@
                                     {
                                       "name": "node-git-server",
                                    -  "version": "0.3.4",
                                    +  "version": "0.4.0",
                                       "description": "🎡 A configurable git server written in Node.js",
                                       "author": "Gabriel J. Csapo ",
                                       "contributors": [
                                    
                                    From f3f73967b2f22b4956bc5a6d1f987b65eed3b91a Mon Sep 17 00:00:00 2001
                                    From: Gabriel Csapo 
                                    Date: Mon, 4 Dec 2017 23:36:54 -0800
                                    Subject: [PATCH 07/14] fixes type to be the same as the event names (#32)
                                    
                                    * fixes type to be the same as the event names
                                    
                                    * updates changelog
                                    ---
                                     CHANGELOG.md     | 4 ++++
                                     README.md        | 4 ++--
                                     example/index.js | 2 +-
                                     lib/git.js       | 7 ++++---
                                     package.json     | 2 +-
                                     5 files changed, 12 insertions(+), 7 deletions(-)
                                    
                                    diff --git a/CHANGELOG.md b/CHANGELOG.md
                                    index 165455e..55cd4b0 100644
                                    --- a/CHANGELOG.md
                                    +++ b/CHANGELOG.md
                                    @@ -1,3 +1,7 @@
                                    +# 0.4.1 (12/04/2017)
                                    +
                                    +- fixes type to be the same as the event names
                                    +
                                     # 0.4.0 (12/03/2017)
                                     
                                     - [BREAKING] changes the interface for authentication to make it more flexible
                                    diff --git a/README.md b/README.md
                                    index d65ba3a..35435ae 100644
                                    --- a/README.md
                                    +++ b/README.md
                                    @@ -2,7 +2,7 @@
                                     
                                     > 🎡 A configurable git server written in Node.js
                                     
                                    ->> there be 🐲 here! The API's and functionality are still be cemented, anything before a 1.0.0 release will be subject to change. 
                                    +>> there be 🐲 here! The API's and functionality are still be cemented, anything before a 1.0.0 release will be subject to change.
                                     
                                     [![Npm Version](https://img.shields.io/npm/v/node-git-server.svg)](https://www.npmjs.com/package/node-git-server)
                                     [![Build Status](https://travis-ci.org/gabrielcsapo/node-git-server.svg?branch=master)](https://travis-ci.org/gabrielcsapo/node-git-server)
                                    @@ -25,7 +25,7 @@ const Server = require('node-git-server');
                                     const repos = new Server(path.resolve(__dirname, 'tmp'), {
                                         autoCreate: true,
                                         authenticate: (type, repo, user, next) => {
                                    -      if(type == 'upload') {
                                    +      if(type == 'push') {
                                             user((username, password) => {
                                               console.log(username, password);
                                               next();
                                    diff --git a/example/index.js b/example/index.js
                                    index 8b43258..1245abf 100644
                                    --- a/example/index.js
                                    +++ b/example/index.js
                                    @@ -8,7 +8,7 @@ const repos = new Server(path.normalize(path.resolve(__dirname, 'tmp')), {
                                         autoCreate: true,
                                         authenticate: (type, repo, user, next) => {
                                           console.log(type, repo); // eslint-disable-line
                                    -      if(type == 'upload') {
                                    +      if(type == 'push') {
                                             user((username, password) => {
                                               console.log(username, password); // eslint-disable-line
                                               next();
                                    diff --git a/lib/git.js b/lib/git.js
                                    index a9939af..d7b4f39 100644
                                    --- a/lib/git.js
                                    +++ b/lib/git.js
                                    @@ -239,16 +239,17 @@ class Git extends EventEmitter {
                                       /**
                                        * returns the typeof service being process
                                        * @method getType
                                    -   * @param  {Service} service - the service type
                                    +   * @param  {String} service - the service type
                                        * @return {String}  - will respond with either upload or download
                                        */
                                       getType(service) {
                                         switch(service) {
                                           case 'upload-pack':
                                    +        return 'fetch';
                                           case 'receive-pack':
                                    -        return 'upload';
                                    +        return 'push';
                                           default:
                                    -        return 'download';
                                    +        return 'unknown';
                                         }
                                       }
                                       /**
                                    diff --git a/package.json b/package.json
                                    index b6a80b1..60ea09e 100644
                                    --- a/package.json
                                    +++ b/package.json
                                    @@ -1,6 +1,6 @@
                                     {
                                       "name": "node-git-server",
                                    -  "version": "0.4.0",
                                    +  "version": "0.4.1",
                                       "description": "🎡 A configurable git server written in Node.js",
                                       "author": "Gabriel J. Csapo ",
                                       "contributors": [
                                    
                                    From 9aec84c8d2f8a472e53fa51c0fd191c10421062a Mon Sep 17 00:00:00 2001
                                    From: Gabriel Csapo 
                                    Date: Thu, 7 Dec 2017 22:09:47 -0800
                                    Subject: [PATCH 08/14] adds https support (#35)
                                    
                                    * adds https support
                                    
                                    * ensures options is set
                                    
                                    * updates readme and adds example for https
                                    
                                    * fixes lint
                                    
                                    * documents git ssl override
                                    ---
                                     CHANGELOG.md            |  4 ++++
                                     README.md               | 24 ++++++++++++++++++++----
                                     example/certificate.pem | 12 ++++++++++++
                                     example/index.js        | 30 ++++++++++++++++++++++++++----
                                     example/privatekey.pem  | 15 +++++++++++++++
                                     lib/git.js              | 18 +++++++++++++++---
                                     6 files changed, 92 insertions(+), 11 deletions(-)
                                     create mode 100644 example/certificate.pem
                                     create mode 100644 example/privatekey.pem
                                    
                                    diff --git a/CHANGELOG.md b/CHANGELOG.md
                                    index 55cd4b0..4922f36 100644
                                    --- a/CHANGELOG.md
                                    +++ b/CHANGELOG.md
                                    @@ -1,3 +1,7 @@
                                    +# Unreleased
                                    +
                                    +- adds https support
                                    +
                                     # 0.4.1 (12/04/2017)
                                     
                                     - fixes type to be the same as the event names
                                    diff --git a/README.md b/README.md
                                    index 35435ae..9cbec6a 100644
                                    --- a/README.md
                                    +++ b/README.md
                                    @@ -21,7 +21,9 @@ npm install node-git-server
                                     # Usage
                                     
                                     ```javascript
                                    +const path = require('path');
                                     const Server = require('node-git-server');
                                    +
                                     const repos = new Server(path.resolve(__dirname, 'tmp'), {
                                         autoCreate: true,
                                         authenticate: (type, repo, user, next) => {
                                    @@ -38,14 +40,12 @@ const repos = new Server(path.resolve(__dirname, 'tmp'), {
                                     const port = process.env.PORT || 7005;
                                     
                                     repos.on('push', (push) => {
                                    -    console.log('push ' + push.repo + '/' + push.commit
                                    -        + ' (' + push.branch + ')'
                                    -    );
                                    +    console.log(`push ${push.repo}/${push.commit} (${push.branch})`);
                                         push.accept();
                                     });
                                     
                                     repos.on('fetch', (fetch) => {
                                    -    console.log('fetch ' + fetch.commit);
                                    +    console.log(`fetch ${fetch.commit}`);
                                         fetch.accept();
                                     });
                                     
                                    @@ -73,6 +73,22 @@ To http://localhost:7005/beep
                                      * [new branch]      master -> master
                                     ```
                                     
                                    +## Example
                                    +
                                    +Running the following command will start up a simple http server:
                                    +
                                    +```
                                    +node example/index.js
                                    +```
                                    +
                                    +If you want to try using https run the following
                                    +
                                    +```
                                    +node example/index.js --https
                                    +```
                                    +
                                    +> When running https with self-signed certs there are two ways to override the git-clients behavior using `git config http.sslVerify false` or `git config --global http.sslCAInfo /path/to/cert.pem`
                                    +
                                     For more information please visit the [docs](http://www.gabrielcsapo.com/node-git-server/code/index.html)
                                     
                                     # Philosophy   
                                    diff --git a/example/certificate.pem b/example/certificate.pem
                                    new file mode 100644
                                    index 0000000..da8d389
                                    --- /dev/null
                                    +++ b/example/certificate.pem
                                    @@ -0,0 +1,12 @@
                                    +-----BEGIN CERTIFICATE-----
                                    +MIIB0TCCAToCCQCvzaaNTZEFTDANBgkqhkiG9w0BAQUFADAtMQswCQYDVQQGEwJV
                                    +UzELMAkGA1UECAwCQ0ExETAPBgNVBAcMCFNhbiBKb3NlMB4XDTE3MTIwNzE5MTI0
                                    +NloXDTE4MDEwNjE5MTI0NlowLTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMREw
                                    +DwYDVQQHDAhTYW4gSm9zZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAplVm
                                    +UrhFbgb+g7gHDjfdTZUwqNnJ6AajytmqmzV7ceTeXKtKfNAN7i2DyFxf/IwQWoxs
                                    +0g7MOE8UP19GCInK0I5T9svvbtSVEfxrtGLMBY7qnojN7Q+DIjdvM7f/m5W8oNkQ
                                    +qb3EzkBKX6A5HobxKqTdu40IBLBkxa0faEmU84MCAwEAATANBgkqhkiG9w0BAQUF
                                    +AAOBgQAzN5VrWE0bFT/UZgUCHrR6h+EQRfGCybAq6MmS1hEoHkLyLPIjokcRWxFe
                                    +eufVyxesJaUiO6f3W34J2NoZK4NsEF931t/n12bB8Ku8H1tokNsyWqJns2Whj+bR
                                    +012osVh6ghdOvKD0yrnv6oLjMU51A8UKuxh51xoMThU0vBwvDg==
                                    +-----END CERTIFICATE-----
                                    diff --git a/example/index.js b/example/index.js
                                    index 1245abf..340f3f1 100644
                                    --- a/example/index.js
                                    +++ b/example/index.js
                                    @@ -1,3 +1,21 @@
                                    +// You Can Use The Commands Below To Generate A Self Signed Certificate For Use With This Tutorial
                                    +// These Commands Require That You have 'openssl' installed on your system
                                    +// openssl genrsa -out privatekey.pem 1024
                                    +// openssl req -new -key privatekey.pem -out certrequest.csr
                                    +// openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem
                                    +
                                    +let type = 'http';
                                    +
                                    +process.argv.slice(2).forEach((arg) => {
                                    +  switch(arg) {
                                    +    case 'https':
                                    +    case '--https':
                                    +      type = 'https';
                                    +    break;
                                    +  }
                                    +});
                                    +
                                    +const fs = require('fs');
                                     const path = require('path');
                                     
                                     const Server = require('../');
                                    @@ -28,14 +46,18 @@ repos.on('push', (push) => {
                                     });
                                     
                                     repos.on('fetch', (fetch) => {
                                    -    console.log('username', fetch.username); // eslint-disable-line
                                    -    console.log('fetch ' + fetch.repo + '/' + fetch.commit); // eslint-disable-line
                                    +    console.log(`username ${fetch.username}`); // eslint-disable-line
                                    +    console.log(`fetch ${fetch.repo}/${fetch.commit}`); // eslint-disable-line
                                         fetch.accept();
                                     });
                                     
                                    -repos.listen(port, (error) => {
                                    +repos.listen(port, {
                                    +  type,
                                    +  key: fs.readFileSync('./privatekey.pem'),
                                    +  cert: fs.readFileSync('./certificate.pem')
                                    +}, (error) => {
                                         if(error) return console.error(`failed to start git-server because of error ${error}`); // eslint-disable-line
                                    -    console.log(`node-git-server running at http://localhost:${port}`); // eslint-disable-line
                                    +    console.log(`node-git-server running at ${type}://localhost:${port}`); // eslint-disable-line
                                         repos.list((err, result) => {
                                             if (!result) {
                                                 console.log("No repositories available..."); // eslint-disable-line
                                    diff --git a/example/privatekey.pem b/example/privatekey.pem
                                    new file mode 100644
                                    index 0000000..eff8a45
                                    --- /dev/null
                                    +++ b/example/privatekey.pem
                                    @@ -0,0 +1,15 @@
                                    +-----BEGIN RSA PRIVATE KEY-----
                                    +MIICWwIBAAKBgQCmVWZSuEVuBv6DuAcON91NlTCo2cnoBqPK2aqbNXtx5N5cq0p8
                                    +0A3uLYPIXF/8jBBajGzSDsw4TxQ/X0YIicrQjlP2y+9u1JUR/Gu0YswFjuqeiM3t
                                    +D4MiN28zt/+blbyg2RCpvcTOQEpfoDkehvEqpN27jQgEsGTFrR9oSZTzgwIDAQAB
                                    +AoGAb3gr6qOzY9ksF/nsQIsPtD6XLZFGzkgk3Hyi6QEeiWVn35KriJmlvEikWFIP
                                    +wZ/cFdKl2uAv3EyitRWUSYSOdcD+tri253WkwpKr8qEq3MKdEsQGZlPiO2MJpWsa
                                    +4vsy1bleUxqbB2TYIIXdjgD8TpTCh8sc8pVxEWEuEThxIIECQQDY9TSZkZHqsqpC
                                    +bK/VUpluj3coZJcczk64ZAdkWYlXfNpvgdT3ViPjpdEYeabzTP0xI7OHkx6fVLiS
                                    +87Y6EwWfAkEAxEQKhgj+saudBzl2EUQW5qntdJh3Fr+OLErSHb4M5E/nWvxW6il0
                                    +XWRE3b7KrikThPkwUtXPTBNGiZ7D1dvfnQJAHMLk5jbWETb+OzANX0pD7NQ4B7LO
                                    +FZOD/A3GrRbxjhePHZkokmFpAJTK02PNLhPWvNzuv9pRBO5GSbTlQ22iIQJAQiEy
                                    +8oqhVrgeRsrjr1mj5cCn07tzlOSiQOZM+dyJd3w81flkR64EGVupoJWisSACBbH4
                                    +yFBmcpmkEMa/8ZUOOQJAfAqyF5aCRh4MbPT7pCGSf0gckc3p6qISb1Zodh7GLSdb
                                    +f/VvQzhRG3MKnSl+ZQ+GQT+F+FeZl0/ZPjVRYG/Avw==
                                    +-----END RSA PRIVATE KEY-----
                                    diff --git a/lib/git.js b/lib/git.js
                                    index d7b4f39..fc91f6e 100644
                                    --- a/lib/git.js
                                    +++ b/lib/git.js
                                    @@ -1,6 +1,7 @@
                                     const fs = require('fs');
                                     const path = require('path');
                                     const http = require('http');
                                    +const https = require('https');
                                     const url = require('url');
                                     const qs = require('querystring');
                                     const httpDuplex = require('./http-duplex');
                                    @@ -427,13 +428,24 @@ class Git extends EventEmitter {
                                        * @method listen
                                        * @memberof Git
                                        * @param  {Number}   port     - the port to start the server on
                                    +   * @param  {Object=}   options  - the options to add extended functionality to the server
                                    +   * @param  {String=}   options.type - this is either https or http (the default is http)
                                    +   * @param  {Buffer|String=}   options.key - the key file for the https server
                                    +   * @param  {Buffer|String=}   options.cert - the cert file for the https server
                                        * @param  {Function} callback - the function to call when server is started or error has occured
                                        */
                                    -  listen(port, callback) {
                                    -      var self = this;
                                    -      this.server = http.createServer(function(req, res) {
                                    +  listen(port, options, callback) {
                                    +      const self = this;
                                    +      if(typeof options == 'function' || !options) {
                                    +        callback = options;
                                    +        options = { type: 'http' };
                                    +      }
                                    +      const createServer = options.type == 'http' ? http.createServer : https.createServer.bind(this, options);
                                    +
                                    +      this.server = createServer(function(req, res) {
                                               self.handle(req, res);
                                           });
                                    +
                                           this.server.listen(port, callback);
                                       }
                                       /**
                                    
                                    From 2d9d4c809ca676b79b67be7d740437d637e0b0b9 Mon Sep 17 00:00:00 2001
                                    From: Gabriel Csapo 
                                    Date: Thu, 7 Dec 2017 22:11:02 -0800
                                    Subject: [PATCH 09/14] 0.4.2 - adds https support
                                    
                                    ---
                                     CHANGELOG.md          |   2 +-
                                     docs/code/Git.html    | 210 +++++++++++++++++++++++++++++++++++++++---
                                     docs/code/git.js.html |  25 +++--
                                     docs/code/global.html |   4 +-
                                     docs/code/index.html  |  21 +++--
                                     package.json          |   2 +-
                                     6 files changed, 231 insertions(+), 33 deletions(-)
                                    
                                    diff --git a/CHANGELOG.md b/CHANGELOG.md
                                    index 4922f36..4bf0891 100644
                                    --- a/CHANGELOG.md
                                    +++ b/CHANGELOG.md
                                    @@ -1,4 +1,4 @@
                                    -# Unreleased
                                    +# 0.4.2 (12/07/2017)
                                     
                                     - adds https support
                                     
                                    diff --git a/docs/code/Git.html b/docs/code/Git.html
                                    index 181a857..3e058ee 100644
                                    --- a/docs/code/Git.html
                                    +++ b/docs/code/Git.html
                                    @@ -65,7 +65,7 @@ 

                                    new GitSource:
                                    @@ -393,7 +393,7 @@

                                    (static) close<
                                    Source:
                                    @@ -477,7 +477,7 @@

                                    (static) creat
                                    Source:
                                    @@ -653,7 +653,7 @@

                                    (static) exist
                                    Source:
                                    @@ -829,7 +829,7 @@

                                    (static) handl
                                    Source:
                                    @@ -985,7 +985,7 @@

                                    (static) listSource:
                                    @@ -1106,7 +1106,7 @@
                                    Parameters:
                                    -

                                    (static) listen(port, callback)

                                    +

                                    (static) listen(port, optionsopt, callback)

                                    @@ -1118,7 +1118,7 @@

                                    (static) liste
                                    Source:
                                    @@ -1184,6 +1184,8 @@

                                    Parameters:
                                    Type + Attributes + @@ -1209,6 +1211,14 @@
                                    Parameters:
                                    + + + + + + + + @@ -1217,6 +1227,168 @@
                                    Parameters:
                                    + + + options + + + + + +Object + + + + + + + + + <optional>
                                    + + + + + + + + + + +

                                    the options to add extended functionality to the server

                                    +
                                    Properties
                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                    NameTypeAttributesDescription
                                    type + + +String + + + + + + <optional>
                                    + + + + + +

                                    this is either https or http (the default is http)

                                    key + + +Buffer +| + +String + + + + + + + + + +

                                    the key file for the https server

                                    cert + + +Buffer +| + +String + + + + + + + + + +

                                    the cert file for the https server

                                    + + + + + + callback @@ -1232,6 +1404,14 @@
                                    Parameters:
                                    + + + + + + + + @@ -1274,7 +1454,7 @@

                                    (static) mkdir<
                                    Source:
                                    @@ -1458,7 +1638,7 @@

                                    fetch

                                    Source:
                                    @@ -1682,7 +1862,7 @@

                                    head

                                    Source:
                                    @@ -1882,7 +2062,7 @@

                                    info

                                    Source:
                                    @@ -2082,7 +2262,7 @@

                                    info

                                    Source:
                                    @@ -2282,7 +2462,7 @@

                                    push

                                    Source:
                                    @@ -2528,7 +2708,7 @@

                                    tag

                                    Source:
                                    diff --git a/docs/code/git.js.html b/docs/code/git.js.html index aa515c1..8435a5f 100644 --- a/docs/code/git.js.html +++ b/docs/code/git.js.html @@ -40,6 +40,7 @@

                                    git.js

                                    const fs = require('fs');
                                     const path = require('path');
                                     const http = require('http');
                                    +const https = require('https');
                                     const url = require('url');
                                     const qs = require('querystring');
                                     const httpDuplex = require('./http-duplex');
                                    @@ -278,16 +279,17 @@ 

                                    git.js

                                    /** * returns the typeof service being process * @method getType - * @param {Service} service - the service type + * @param {String} service - the service type * @return {String} - will respond with either upload or download */ getType(service) { switch(service) { case 'upload-pack': + return 'fetch'; case 'receive-pack': - return 'upload'; + return 'push'; default: - return 'download'; + return 'unknown'; } } /** @@ -465,13 +467,24 @@

                                    git.js

                                    * @method listen * @memberof Git * @param {Number} port - the port to start the server on + * @param {Object=} options - the options to add extended functionality to the server + * @param {String=} options.type - this is either https or http (the default is http) + * @param {Buffer|String=} options.key - the key file for the https server + * @param {Buffer|String=} options.cert - the cert file for the https server * @param {Function} callback - the function to call when server is started or error has occured */ - listen(port, callback) { - var self = this; - this.server = http.createServer(function(req, res) { + listen(port, options, callback) { + const self = this; + if(typeof options == 'function' || !options) { + callback = options; + options = { type: 'http' }; + } + const createServer = options.type == 'http' ? http.createServer : https.createServer.bind(this, options); + + this.server = createServer(function(req, res) { self.handle(req, res); }); + this.server.listen(port, callback); } /** diff --git a/docs/code/global.html b/docs/code/global.html index 669d106..cd62fad 100644 --- a/docs/code/global.html +++ b/docs/code/global.html @@ -127,7 +127,7 @@

                                    getTypeSource:
                                    @@ -211,7 +211,7 @@
                                    Parameters:
                                    -Service +String diff --git a/docs/code/index.html b/docs/code/index.html index 34fb666..d1181b8 100644 --- a/docs/code/index.html +++ b/docs/code/index.html @@ -49,7 +49,7 @@

                                    Home

                                    Classes

                                    • node-git-server

                                      🎡 A configurable git server written in Node.js

                                      -

                                      there be 🐲 here! The API's and functionality are still be cemented, anything before a 1.0.0 release will be subject to change.

                                      +

                                      there be 🐲 here! The API's and functionality are still be cemented, anything before a 1.0.0 release will be subject to change.

                                      Npm Version @@ -59,11 +59,13 @@

                                      Home

                                      Classes

                                      • devDependency Status npm npm

                                        -

                                        Install

                                        npm install node-git-server

                                        Usage

                                        const Server = require('node-git-server');
                                        +

                                        Install

                                        npm install node-git-server

                                        Usage

                                        const path = require('path');
                                        +const Server = require('node-git-server');
                                        +
                                         const repos = new Server(path.resolve(__dirname, 'tmp'), {
                                             autoCreate: true,
                                             authenticate: (type, repo, user, next) => {
                                        -      if(type == 'upload') {
                                        +      if(type == 'push') {
                                                 user((username, password) => {
                                                   console.log(username, password);
                                                   next();
                                        @@ -76,14 +78,12 @@ 

                                        Install

                                        npm install node-git-serve
                                         const port = process.env.PORT || 7005;
                                         
                                         repos.on('push', (push) => {
                                        -    console.log('push ' + push.repo + '/' + push.commit
                                        -        + ' (' + push.branch + ')'
                                        -    );
                                        +    console.log(`push ${push.repo}/${push.commit} (${push.branch})`);
                                             push.accept();
                                         });
                                         
                                         repos.on('fetch', (fetch) => {
                                        -    console.log('fetch ' + fetch.commit);
                                        +    console.log(`fetch ${fetch.commit}`);
                                             fetch.accept();
                                         });
                                         
                                        @@ -98,7 +98,12 @@ 

                                        Install

                                        npm install node-git-serve
                                         Writing objects: 100% (356/356), 46.20 KiB, done.
                                         Total 356 (delta 210), reused 355 (delta 210)
                                         To http://localhost:7005/beep
                                        - * [new branch]      master -> master

                                        For more information please visit the docs

                                        + * [new branch] master -> master

                                        Example

                                        Running the following command will start up a simple http server:

                                        +
                                        node example/index.js

                                        If you want to try using https run the following

                                        +
                                        node example/index.js --https
                                        +

                                        When running https with self-signed certs there are two ways to override the git-clients behavior using git config http.sslVerify false or git config --global http.sslCAInfo /path/to/cert.pem

                                        +
                                        +

                                        For more information please visit the docs

                                        Philosophy

                                        This library is aimed to have a zero dependency footprint. If you are reading this and you see dependencies, help to remove them 🐒.

                                        Thanks

                                        This is a hard fork from pushover.

                                  diff --git a/package.json b/package.json index 60ea09e..30e55e0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-git-server", - "version": "0.4.1", + "version": "0.4.2", "description": "🎡 A configurable git server written in Node.js", "author": "Gabriel J. Csapo ", "contributors": [ From 415e23d4f530e8d4bd22314e2f7917f9a8a7a01a Mon Sep 17 00:00:00 2001 From: Gabriel Csapo Date: Fri, 12 Jan 2018 23:02:32 -0800 Subject: [PATCH 10/14] updates tryitout and docs --- tryitout.js => .tryitout | 9 +- docs/index.html | 4241 +++++++++++++++++++++++++++++++++++++- docs/krayon.css | 18 + docs/krayon.min.js | 1 + docs/main.js | 5 + package.json | 6 +- 6 files changed, 4273 insertions(+), 7 deletions(-) rename tryitout.js => .tryitout (84%) create mode 100644 docs/krayon.css create mode 100644 docs/krayon.min.js create mode 100644 docs/main.js diff --git a/tryitout.js b/.tryitout similarity index 84% rename from tryitout.js rename to .tryitout index 9a7d639..cf355f4 100644 --- a/tryitout.js +++ b/.tryitout @@ -9,7 +9,7 @@ module.exports = { body: `

                                  ${description}

                                  -
                                  +        
                                         const Server = require('node-git-server');
                                         const repo = new Server(path.resolve(__dirname, 'tmp'), {
                                             autoCreate: true,
                                  @@ -33,5 +33,10 @@ module.exports = {
                                          
                                  Made with ☕️ by @gabrielcsapo
                                  `, template: 'landing', - output: './docs' + output: './docs', + externals: [ + "./docs/krayon.css", + "./docs/krayon.min.js", + "./docs/main.js" + ] }; diff --git a/docs/index.html b/docs/index.html index 486061a..be82179 100644 --- a/docs/index.html +++ b/docs/index.html @@ -5,8 +5,4245 @@ - +
                                  - + diff --git a/docs/krayon.css b/docs/krayon.css new file mode 100644 index 0000000..9c4af13 --- /dev/null +++ b/docs/krayon.css @@ -0,0 +1,18 @@ +.string { + color: #032f62 +} +.keyword { + color: #d73a49 +} +.operator { + color: #d73a49 +} +.function { + color: #005cc5 +} +.class { + color: #6f42c1 +} +.comment { + color: #6a737d +} diff --git a/docs/krayon.min.js b/docs/krayon.min.js new file mode 100644 index 0000000..0fa690d --- /dev/null +++ b/docs/krayon.min.js @@ -0,0 +1 @@ +require=function b(c,d,e){function a(h,i){if(!d[h]){if(!c[h]){var j="function"==typeof require&&require;if(!i&&j)return j(h,!0);if(g)return g(h,!0);var k=new Error("Cannot find module '"+h+"'");throw k.code="MODULE_NOT_FOUND",k}var f=d[h]={exports:{}};c[h][0].call(f.exports,function(b){var d=c[h][1][b];return a(d?d:b)},f,f.exports,b,c,d,e)}return d[h].exports}for(var g="function"==typeof require&&require,f=0;f127127{a=a.replace(e[b],(a,d)=>{let e=a.replace(d,"");return`{#${b}#${c(d)}#}${e}`})}),a.replace(/\{#([a-z]+)#(.*?)#\}/g,(a,b,c)=>""+d(c)+"")}},{"./util.js":1}]},{},[]); \ No newline at end of file diff --git a/docs/main.js b/docs/main.js new file mode 100644 index 0000000..f28f335 --- /dev/null +++ b/docs/main.js @@ -0,0 +1,5 @@ +window.onload = function() { + var Krayon = require('krayon'); + + document.querySelector('#code').innerHTML = Krayon(document.querySelector('#code').innerHTML); +} diff --git a/package.json b/package.json index 30e55e0..5263a6b 100644 --- a/package.json +++ b/package.json @@ -34,10 +34,10 @@ "devDependencies": { "async": "^2.6.0", "docdash": "^0.4.0", - "eslint": "^4.11.0", + "eslint": "^4.15.0", "jsdoc": "^3.5.5", - "tap": "^10.7.3", + "tap": "^11.0.1", "tape": "^4.8.0", - "tryitout": "^1.2.0" + "tryitout": "^2.0.6" } } From 82028631236f3e7cfda80f76e8f5e530aee0a10c Mon Sep 17 00:00:00 2001 From: hasezoey <10911626+hasezoey@users.noreply.github.com> Date: Tue, 29 May 2018 23:44:08 +0200 Subject: [PATCH 11/14] Fix for #38 (#39) * gitignore update for visual studio, Buffer Fix #38 * Update util.js * Update service.js --- .gitignore | 1 + lib/service.js | 4 ++-- lib/util.js | 2 +- test/fixtures/server/tmp/test.git/hooks/applypatch-msg.sample | 0 test/fixtures/server/tmp/test.git/hooks/commit-msg.sample | 0 test/fixtures/server/tmp/test.git/hooks/post-update.sample | 0 test/fixtures/server/tmp/test.git/hooks/pre-applypatch.sample | 0 test/fixtures/server/tmp/test.git/hooks/pre-commit.sample | 0 test/fixtures/server/tmp/test.git/hooks/pre-push.sample | 0 test/fixtures/server/tmp/test.git/hooks/pre-rebase.sample | 0 .../server/tmp/test.git/hooks/prepare-commit-msg.sample | 0 test/fixtures/server/tmp/test.git/hooks/update.sample | 0 12 files changed, 4 insertions(+), 3 deletions(-) mode change 100755 => 100644 test/fixtures/server/tmp/test.git/hooks/applypatch-msg.sample mode change 100755 => 100644 test/fixtures/server/tmp/test.git/hooks/commit-msg.sample mode change 100755 => 100644 test/fixtures/server/tmp/test.git/hooks/post-update.sample mode change 100755 => 100644 test/fixtures/server/tmp/test.git/hooks/pre-applypatch.sample mode change 100755 => 100644 test/fixtures/server/tmp/test.git/hooks/pre-commit.sample mode change 100755 => 100644 test/fixtures/server/tmp/test.git/hooks/pre-push.sample mode change 100755 => 100644 test/fixtures/server/tmp/test.git/hooks/pre-rebase.sample mode change 100755 => 100644 test/fixtures/server/tmp/test.git/hooks/prepare-commit-msg.sample mode change 100755 => 100644 test/fixtures/server/tmp/test.git/hooks/update.sample diff --git a/.gitignore b/.gitignore index c22ee1e..4fd2111 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ coverage example/test example/tmp package-lock.json +.vs/ \ No newline at end of file diff --git a/lib/service.js b/lib/service.js index 0f50176..4af2f20 100644 --- a/lib/service.js +++ b/lib/service.js @@ -50,7 +50,7 @@ class Service extends HttpDuplex { if(req.headers["authorization"]) { const tokens = req.headers["authorization"].split(" "); if (tokens[0] === "Basic") { - const splitHash = new Buffer(tokens[1], 'base64').toString('utf8').split(":"); + const splitHash = new Buffer.from(tokens[1], 'base64').toString('utf8').split(":"); this.username = splitHash.shift(); } } @@ -116,7 +116,7 @@ class Service extends HttpDuplex { self.emit('response', respStream, function endResponse() { - res.queue(new Buffer('0000')); + res.queue(new Buffer.from('0000')); res.queue(null); }); ps.stdout.pipe(respStream).pipe(res); diff --git a/lib/util.js b/lib/util.js index 3d187d3..5720a3f 100644 --- a/lib/util.js +++ b/lib/util.js @@ -34,7 +34,7 @@ const Util = { } else { const tokens = req.headers["authorization"].split(" "); if (tokens[0] === "Basic") { - const splitHash = new Buffer(tokens[1], 'base64').toString('utf8').split(":"); + const splitHash = new Buffer.from(tokens[1], 'base64').toString('utf8').split(":"); const username = splitHash.shift(); const password = splitHash.join(":"); callback(username, password, null); diff --git a/test/fixtures/server/tmp/test.git/hooks/applypatch-msg.sample b/test/fixtures/server/tmp/test.git/hooks/applypatch-msg.sample old mode 100755 new mode 100644 diff --git a/test/fixtures/server/tmp/test.git/hooks/commit-msg.sample b/test/fixtures/server/tmp/test.git/hooks/commit-msg.sample old mode 100755 new mode 100644 diff --git a/test/fixtures/server/tmp/test.git/hooks/post-update.sample b/test/fixtures/server/tmp/test.git/hooks/post-update.sample old mode 100755 new mode 100644 diff --git a/test/fixtures/server/tmp/test.git/hooks/pre-applypatch.sample b/test/fixtures/server/tmp/test.git/hooks/pre-applypatch.sample old mode 100755 new mode 100644 diff --git a/test/fixtures/server/tmp/test.git/hooks/pre-commit.sample b/test/fixtures/server/tmp/test.git/hooks/pre-commit.sample old mode 100755 new mode 100644 diff --git a/test/fixtures/server/tmp/test.git/hooks/pre-push.sample b/test/fixtures/server/tmp/test.git/hooks/pre-push.sample old mode 100755 new mode 100644 diff --git a/test/fixtures/server/tmp/test.git/hooks/pre-rebase.sample b/test/fixtures/server/tmp/test.git/hooks/pre-rebase.sample old mode 100755 new mode 100644 diff --git a/test/fixtures/server/tmp/test.git/hooks/prepare-commit-msg.sample b/test/fixtures/server/tmp/test.git/hooks/prepare-commit-msg.sample old mode 100755 new mode 100644 diff --git a/test/fixtures/server/tmp/test.git/hooks/update.sample b/test/fixtures/server/tmp/test.git/hooks/update.sample old mode 100755 new mode 100644 From 21dc88ee293a3130bd1af2a30da3c1d6e9714d47 Mon Sep 17 00:00:00 2001 From: Gabriel Csapo Date: Wed, 30 May 2018 20:42:04 -0700 Subject: [PATCH 12/14] 0.4.3 - removes deprecated Buffer interface --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bf0891..7f786fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.4.3 (04/30/2018) + +- removes deprecated `Buffer` interface + # 0.4.2 (12/07/2017) - adds https support diff --git a/package.json b/package.json index 5263a6b..f1fb260 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-git-server", - "version": "0.4.2", + "version": "0.4.3", "description": "🎡 A configurable git server written in Node.js", "author": "Gabriel J. Csapo ", "contributors": [ From 3243df826f6ee9cebb85e7b0250ac3e609c686d8 Mon Sep 17 00:00:00 2001 From: jaywcjlove <398188662@qq.com> Date: Sat, 11 Aug 2018 12:38:03 +0800 Subject: [PATCH 13/14] Change document tool; --- .gitignore | 3 +- docma.json | 59 + docs/index.html | 4260 +---------------------------------------------- package.json | 8 +- 4 files changed, 84 insertions(+), 4246 deletions(-) create mode 100644 docma.json diff --git a/.gitignore b/.gitignore index 4fd2111..f5960fe 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ coverage example/test example/tmp package-lock.json -.vs/ \ No newline at end of file +.vs/ +docs \ No newline at end of file diff --git a/docma.json b/docma.json new file mode 100644 index 0000000..42f9f7e --- /dev/null +++ b/docma.json @@ -0,0 +1,59 @@ +{ + "template": { + "options": { + "title": { + "label": "node-git-server", + "href": "/" + }, + "contentView": { + "bookmarks": true + }, + "sidebar": { + "enabled": true, + "outline": "tree", + "collapsed": false, + "toolbar": true, + "itemsFolded": false, + "itemsOverflow": "crop", + "badges": true, + "search": true, + "animations": true + }, + "navbar": { + "enabled": true, + "dark": false, + "animations": true, + "menu": [ + { + "label": "Docs", + "iconClass": "fas fa-book", + "href": "./" + }, + { + "label": "Download", + "iconClass": "fas fa-cloud-download-alt", + "items": [ + { + "label": "v0.5.0-pre", + "href": "https://github.com/user/repo/archive/v0.7.0-pre.zip" + }, + { + "separator": true + }, + { + "label": "v1.0.0", + "href": "https://github.com/user/repo/archive/v1.0.0.zip" + } + ] + }, + { + "label": "GitHub", + "iconClass": "fab fa-github", + "href": "https://github.com/gabrielcsapo/node-git-server", + "target": "_blank" + } + ] + } + } + } +} \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index be82179..0ad5924 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,4249 +1,27 @@ - - - - - - - -
                                  - + + + + + + -if (true) { - module.exports = __webpack_require__(14); -} else { - module.exports = require('./cjs/react.development.js'); -} + +
                                  -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -if (false) { - var REACT_ELEMENT_TYPE = (typeof Symbol === 'function' && - Symbol.for && - Symbol.for('react.element')) || - 0xeac7; - - var isValidElement = function(object) { - return typeof object === 'object' && - object !== null && - object.$$typeof === REACT_ELEMENT_TYPE; - }; - - // By explicitly using `prop-types` you are opting into new development behavior. - // http://fb.me/prop-types-in-prod - var throwOnDirectAccess = true; - module.exports = require('./factoryWithTypeCheckers')(isValidElement, throwOnDirectAccess); -} else { - // By explicitly using `prop-types` you are opting into new production behavior. - // http://fb.me/prop-types-in-prod - module.exports = __webpack_require__(15)(); -} - - -/***/ }), -/* 2 */ -/***/ (function(module, exports) { - -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ -// css base code, injected by the css-loader -module.exports = function(useSourceMap) { - var list = []; - - // return the list of modules as css string - list.toString = function toString() { - return this.map(function (item) { - var content = cssWithMappingToString(item, useSourceMap); - if(item[2]) { - return "@media " + item[2] + "{" + content + "}"; - } else { - return content; - } - }).join(""); - }; - - // import a list of modules into the list - list.i = function(modules, mediaQuery) { - if(typeof modules === "string") - modules = [[null, modules, ""]]; - var alreadyImportedModules = {}; - for(var i = 0; i < this.length; i++) { - var id = this[i][0]; - if(typeof id === "number") - alreadyImportedModules[id] = true; - } - for(i = 0; i < modules.length; i++) { - var item = modules[i]; - // skip already imported module - // this implementation is not 100% perfect for weird media query combinations - // when a module is imported multiple times with different media queries. - // I hope this will never occur (Hey this way we have smaller bundles) - if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) { - if(mediaQuery && !item[2]) { - item[2] = mediaQuery; - } else if(mediaQuery) { - item[2] = "(" + item[2] + ") and (" + mediaQuery + ")"; - } - list.push(item); - } - } - }; - return list; -}; - -function cssWithMappingToString(item, useSourceMap) { - var content = item[1] || ''; - var cssMapping = item[3]; - if (!cssMapping) { - return content; - } - - if (useSourceMap && typeof btoa === 'function') { - var sourceMapping = toComment(cssMapping); - var sourceURLs = cssMapping.sources.map(function (source) { - return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */' - }); - - return [content].concat(sourceURLs).concat([sourceMapping]).join('\n'); - } - - return [content].join('\n'); -} - -// Adapted from convert-source-map (MIT) -function toComment(sourceMap) { - // eslint-disable-next-line no-undef - var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))); - var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64; - - return '/*# ' + data + ' */'; -} - - -/***/ }), -/* 3 */ -/***/ (function(module, exports, __webpack_require__) { - -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ - -var stylesInDom = {}; - -var memoize = function (fn) { - var memo; - - return function () { - if (typeof memo === "undefined") memo = fn.apply(this, arguments); - return memo; - }; -}; - -var isOldIE = memoize(function () { - // Test for IE <= 9 as proposed by Browserhacks - // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805 - // Tests for existence of standard globals is to allow style-loader - // to operate correctly into non-standard environments - // @see https://github.com/webpack-contrib/style-loader/issues/177 - return window && document && document.all && !window.atob; -}); - -var getElement = (function (fn) { - var memo = {}; - - return function(selector) { - if (typeof memo[selector] === "undefined") { - var styleTarget = fn.call(this, selector); - // Special case to return head of iframe instead of iframe itself - if (styleTarget instanceof window.HTMLIFrameElement) { - try { - // This will throw an exception if access to iframe is blocked - // due to cross-origin restrictions - styleTarget = styleTarget.contentDocument.head; - } catch(e) { - styleTarget = null; - } - } - memo[selector] = styleTarget; - } - return memo[selector] - }; -})(function (target) { - return document.querySelector(target) -}); - -var singleton = null; -var singletonCounter = 0; -var stylesInsertedAtTop = []; - -var fixUrls = __webpack_require__(11); - -module.exports = function(list, options) { - if (typeof DEBUG !== "undefined" && DEBUG) { - if (typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment"); - } - - options = options || {}; - - options.attrs = typeof options.attrs === "object" ? options.attrs : {}; - - // Force single-tag solution on IE6-9, which has a hard limit on the # of