oscarngncc / COMP4111_project

COMP4111 project
0 stars 0 forks source link

All requests return Bad Request #24

Open Derppening opened 4 years ago

Derppening commented 4 years ago

Issue description

Submitting any request to the server results in the server responding with 400 Bad Request.

Steps to reproduce this issue

  1. Set up the database as stated in the README.
  2. Run the project, either via IntelliJ IDEA or the provided JAR.
  3. Make any request.

What's the expected result?

A valid request should return 200 OK.

What's the actual result?

All requests returns 400 Bad Request.

curl -v -X POST --data "{\"Username\": \"user00001\", \"Password\": \"pass00001\"}" http://localhost:8080/BookManagementService/login
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying ::1:8080...
* Connected to localhost (::1) port 8080 (#0)
> POST /BookManagementService/login HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.70.0
> Accept: */*
> Content-Length: 50
> Content-Type: application/x-www-form-urlencoded
> 
* upload completely sent off: 50 out of 50 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 400 Bad Request
< Date: Sun, 31 May 2020 16:24:25 GMT
< Server: Test/1.1
< Content-Length: 0
< Connection: Close
< 
* Closing connection 0

Additional Information

Since I still have the implementation to test, I decided to do some debugging and dig into the cause. It turns out that the cause is a NullPointerException that may occur if the application does not have access to the database:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Access denied for user 'sqlUser'@'%' to database 'lbm'
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
    at com.mysql.jdbc.Util.getInstance(Util.java:408)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:944)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3933)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3869)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:864)
    at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1707)
    at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1217)
    at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2189)
    at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2220)
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2015)
    at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:768)
    at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
    at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:385)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:323)
    at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
    at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:228)
    at helper.SqlSingleton.getConnection(SqlSingleton.java:58)
    at helper.SqlHelpers.DeleteToken(SqlHelpers.java:74)
    at handler.HttpLogoutHandler.handleInternal(HttpLogoutHandler.java:47)
    at handler.HttpLogoutHandler.handle(HttpLogoutHandler.java:31)
    at org.apache.http.nio.protocol.HttpAsyncService.responseReady(HttpAsyncService.java:480)
    at org.apache.http.impl.nio.DefaultNHttpServerConnection.produceOutput(DefaultNHttpServerConnection.java:306)
    at org.apache.http.impl.nio.DefaultHttpServerIODispatch.onOutputReady(DefaultHttpServerIODispatch.java:248)
    at org.apache.http.impl.nio.DefaultHttpServerIODispatch.onOutputReady(DefaultHttpServerIODispatch.java:57)
    at org.apache.http.impl.nio.reactor.AbstractIODispatch.outputReady(AbstractIODispatch.java:145)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.writable(BaseIOReactor.java:187)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:341)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
    at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591)
    at java.base/java.lang.Thread.run(Thread.java:834)

As for why the database is not accessible, I noticed that the cause is due to bad capitalization. In particular, the database created by schema.sql is LBM whereas the database connection points to jdbc:mysql://localhost:3306/lbm. According to this and this, on Linux the SQL server is defaulted to making database and table names case-sensitive. This explains why trying to access the database LBM via the connection URL does not work as intended on Linux.

HowardLing2119 commented 4 years ago

You can specify the hostname in args, I don't know if it is a bug or not.