Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding DBGp Proxy support #280

Closed
wants to merge 21 commits into from
Closed

Adding DBGp Proxy support #280

wants to merge 21 commits into from

Conversation

SidIcarus
Copy link

@SidIcarus SidIcarus commented Jun 25, 2018

Related #107, #110 , #111, & #274
successfully allows for multiple concurrent connections to a double nat'd network

  • Handle response data
  • tests
    • errors: timeout, failure to resolve, duplicate key, no key
    • successful registration, de-registration
  • proxy error command

@codecov
Copy link

codecov bot commented Jun 25, 2018

Codecov Report

Merging #280 into master will increase coverage by 0.37%.
The diff coverage is 70.37%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #280      +/-   ##
==========================================
+ Coverage   70.11%   70.49%   +0.37%     
==========================================
  Files           5        6       +1     
  Lines        1014     1088      +74     
  Branches      161      182      +21     
==========================================
+ Hits          711      767      +56     
- Misses        303      321      +18
Impacted Files Coverage Δ
src/terminal.ts 9.37% <0%> (ø) ⬆️
src/xdebugConnection.ts 84.53% <100%> (ø) ⬆️
src/phpDebug.ts 65.61% <23.52%> (-1.33%) ⬇️
src/proxyConnect.ts 89.65% <89.65%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c7280b6...99ee211. Read the comment docs.

Copy link
Contributor

@felixfbecker felixfbecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks much cleaner!

src/xdebugConnection.ts Outdated Show resolved Hide resolved
src/xdebugConnection.ts Outdated Show resolved Hide resolved
src/phpDebug.ts Outdated Show resolved Hide resolved
@felixfbecker felixfbecker changed the title Adding DBGp Proxy support WIP: Adding DBGp Proxy support Jun 25, 2018
@SidIcarus SidIcarus force-pushed the master branch 2 times, most recently from 6e2d704 to 0b25edb Compare June 29, 2018 20:11
@SidIcarus SidIcarus changed the title WIP: Adding DBGp Proxy support Adding DBGp Proxy support Jun 29, 2018
@SidIcarus
Copy link
Author

@felixfbecker i think its ready for integration

We also needed to add some code to the python proxy. We are forwarding it to the github owner of komodo so he can forward it to their repo maintainers as they don't have a public facing repo for it.

@SidIcarus SidIcarus force-pushed the master branch 2 times, most recently from ac9c919 to 7b33cf2 Compare July 2, 2018 17:34
@SidIcarus
Copy link
Author

@felixfbecker
We haven't implemented support for the proxyerror command.

It currently will log this in xdebug.remote_log

<- proxyerror -i 1 -- sessionHash ->
<response xmlns="urn:debugger_protocol_v1"
    xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="proxyerror" transaction_id="1">
    <error code="4">
        <message>
            <![CDATA[unimplemented command]]>
        </message>
    </error>
</response>

Would you have any time to look into implementing that?
If not, I can do so just not immediately; is it fine to get this PR integrated without it?

@felixfbecker
Copy link
Contributor

Realistically I am too short on time and personal benefits from this project to invest actual coding into it anymore, but I'll take some time to review. What is the proxyerror command for?

@SidIcarus
Copy link
Author

SidIcarus commented Jul 2, 2018

Understandable.
They are error messages that the proxy would emit itself.

msg = "No server with key [%s], stopping request [%r]"% (idekey, session)
...
msg = "Unable to connect to server with key [%s], stopping request [%r]"% (idekey, session)
...
msg = "outputHandler Closing connection, invalid protocol used"
...
msg = "responseHandler Closing connection, invalid protocol used"
...
msg = "Unable to connect to the server listener %s:%d [%r]" % \
...
msg = "Closing connection, invalid protocol used"
...
error(msg)
...
    def error(self, msg):
        if not self._socket:
            log.error(msg)
            return
        self.sendCommand(['proxyerror'], msg)
...
    def sendCommand(self, argv, data = None):
        if not self._socket:
            raise DBGPError('Socket disconnected', ERROR_EXCEPTION)
        self._transaction_id = self._transaction_id + 1

        argv += ['-i', str(self._transaction_id)]
        if data:
            argv += ['--', base64.encodestring(data).strip()]
            
        # if the args need quoting, it will happen here, argv2line doesn't
        # handle it all
        # cmdline = listcmd.argv2line(argv)
        escapedArgs = []
        for arg in argv:
            # we must escape any quotes in the argument
            arg = self._re_escape.sub(r'\\\1', arg)
            if ' ' in arg or '"' in arg or "'" in arg or '\\' in arg:
                arg = '"'+arg+'"'
            escapedArgs.append(str(arg))
        cmdline = ' '.join(escapedArgs)
        try:
            #print "sendCommand: %s"% cmdline
            log.debug("sendCommand: %s", cmdline)
            self._socket.sendall(cmdline+'\0')
            #log.debug("sendCommand: %s DONE", cmdline)
        except socket.error as e:
            log.error("session sendCommand socket error %r", e)
            self._stop = 1
        return self._transaction_id

@felixfbecker
Copy link
Contributor

I think error handling is important or its gonna create a maintenance burden when users don't know why something is not working and will file issues.
It shouldn't be hard to implement, right?

@towhidabsar
Copy link
Contributor

towhidabsar commented Jul 3, 2018

Hi @felixfbecker , I looked into implementing the fix for proxyerror but it seems our first assumption was wrong. proxyerroris sent to XDebug server and not the IDE. As a result, we don't need to handle it in the debugger. So the code should be complete as is.
Please review it and let us know if there is anything else of concern.

@towhidabsar
Copy link
Contributor

@felixfbecker Did you get a chance to review the code?

@SidIcarus
Copy link
Author

@felixfbecker when do you think you'll be able to integrate this PR in?

Copy link
Contributor

@felixfbecker felixfbecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I was on vacation. See comments

src/proxyConnect.ts Outdated Show resolved Hide resolved
this._key = key
this._port = port
this._timeout = timeout
this.msgs = new Map([
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a Map with string identifiers for this means it is not typesafe. When these are only used once, I would inline these. If they are needed multiple times, define a method that returns it.

Copy link
Author

@SidIcarus SidIcarus Jul 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is it not typesafe? It specifies type in its declaration on line 25: public msgs: Map<string, string>.
A method would justifiable if the msgs had a way to change but there isn't and they don't.
Using a map allowed us to group their intended functionality whilst reducing variable name verbosity.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When calling msgs.get() you could easily have a typo in the key. You also get no autocompletion for the keys.

An object would also be fine.

Copy link
Author

@SidIcarus SidIcarus Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    
    public msgs:{ [key:string]: string } = {}
    constructor() {
        ...
        this.msgs = {
            defaultError: 'Unknown Error',
            deregisterInfo: `Deregistering ${this._key} with proxy @ ${this._host}:${this._port}`,
            deregisterSuccess: 'Deregistration successful',
            duplicateKey: 'IDE Key already exists',
            nonexistentKey: 'No IDE key',
            registerInfo: `Registering ${this._key} with proxy @ ${this._host}:${this._port}`,
            registerSuccess: 'Registration successful',
            resolve: `Failure to resolve ${this._host}`,
            timeout: `Timeout connecting to ${this._host}:${this._port}`,
        }
        ...
    }

This should cover it, yes?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, because the key is still string. But if you move the object from the constructor to the initialiser instead and let the type be inferred, it would be safe.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@felixfbecker included an interface defining ProxyMessages to ensure the key is type safe.

src/proxyConnect.ts Show resolved Hide resolved
/** proxy response data parser */
private _parser = new DOMParser()
/** tcp connection to communicate with proxy server */
public _socket = new Socket()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this public?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, when we began writing our tests we mocked out the socket and such but weren't completely successful. We opted to make the socket public and that allowed us to test each step.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way the test uses this should-be private property to assert things looks very hacky to me, as it is making use of internals and testing implementation details. I am not confident I would be able to maintain and support this code if issues pop up. Please see if you can find a way to define clear interface boundaries and to test at those boundaries.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@felixfbecker I changed it back to private and followed the convention you used to pass in the socket in the constructor. Please let me know if this is acceptable.

@SidIcarus
Copy link
Author

I've rebased our fork and resolved the files in conflict. Once the current comments are resolved, I can push that up.

@felixfbecker
Copy link
Contributor

I replied a week ago, please take a look at my questions above

@SidIcarus SidIcarus force-pushed the master branch 2 times, most recently from 4421096 to 60d28bc Compare August 15, 2018 15:42
@towhidabsar
Copy link
Contributor

@felixfbecker please take a look. Updated the branch to have all the builds pass, and re-tested the code.

@SidIcarus SidIcarus force-pushed the master branch 5 times, most recently from 38a4712 to b96010d Compare October 15, 2018 16:14
…ivate

- new ProxyMessage interface to ensure typesafe messages
- socket is now private and can be passed through constructor
@towhidabsar
Copy link
Contributor

@felixfbecker ping. Please let me know if the recent commits address your concerns?

@bilogic
Copy link

bilogic commented May 11, 2019

it's odd how slowly this moves.

@nn-hh
Copy link

nn-hh commented Jun 7, 2019

@felixfbecker Please.

@bilogic
Copy link

bilogic commented Jun 19, 2019

@SidIcarus can you provide some instructions on how to load your extension in vscode?

@bilogic
Copy link

bilogic commented Jul 2, 2019

has everyone given up?

@X-Coder
Copy link

X-Coder commented Jul 2, 2019

Hope not, because its good work and very useful for me.

@bilogic For my smaller customizations I installed the extensions as usual and manually patched the files in C:\Users%USERNAME%.vscode\extensions\felixfbecker.php-debug-1.13.0\out.
This is not the best way and needs to be done each time the extensions updates.

The files from SidIcarus are source files written in TypeScript and these needs to be compiled into normal javascript before you can use them.

@towhidabsar
Copy link
Contributor

Hi, sorry @SidIcarus and I are still waiting on @felixfbecker to check out and give us feedback on the latest commits.
In the meantime if you want to try out the extension, you can just clone my repository and do the following:
npm run build
npm install -g vsce if you don't have the vsce package
vsce package inside the folder will generate the vsix file
Then just install the extension using the generated VSIX in vscode.
But hopefully we can get this merged in as soon as possible.

@zobo
Copy link
Contributor

zobo commented Jul 15, 2019

@felixfbecker I have created a PR to the forked repo with some fixes and extensions. Since there was no response in over a week, I'm linking it here and if needed I can rebase things an create a new PR here. Link: towhidabsar#1

@BurningDog
Copy link

This would be super useful to myself and my team, and for anyone running php inside kubernetes/docker.

What would the next step be here? Are we waiting for responses from @felixfbecker?

@zobo
Copy link
Contributor

zobo commented Nov 15, 2019

Seems so... I tried reaching out, but got no response. I'll probably fork and re-publish the plugin on the store just so that our team can use these features.

Copy link
Contributor

@felixfbecker felixfbecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks well-implemented. I won't be able to maintain this though because I don't use a proxy. Would anyone be willing to take maintenance of this part of the codebase after merge?

@felixfbecker
Copy link
Contributor

@zobo what about your PR towhidabsar#1 it block merging this?

@zobo
Copy link
Contributor

zobo commented Nov 15, 2019

Hi @felixfbecker I believe it got stuck there also. I can reach out again, but could also just make a PR against the merged code. I think there are some issues with the PR without my latest changes. Let me check and get back to you.

@felixfbecker
Copy link
Contributor

You could just open the PR here including both this PR and your fixes

@zobo
Copy link
Contributor

zobo commented Nov 15, 2019

Ok, I'll make a new PR.

@zobo
Copy link
Contributor

zobo commented Nov 15, 2019

Created #378 that should be merged after this one. I plan to open at least one more proxy related PR, but not right away.
There are however some other PRs that could use some love :)

@felixfbecker
Copy link
Contributor

@SidIcarus it seems that the changes you made to install PHP on macOS in Travis ar e no longer working and the build is failing now :/
Do you have an idea why?

@MurzNN
Copy link

MurzNN commented Sep 28, 2020

Seems this PR is still not merged, what is the current stoppers for finish and merge this PR?

@felixfbecker felixfbecker changed the base branch from master to main December 21, 2020 20:20
@zobo
Copy link
Contributor

zobo commented Nov 3, 2021

PR #685 re-implements this. The base was sadly so far off that I could not merge and fix it.

@zobo zobo closed this Nov 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants