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

Status code 405 returned for the first POST call of the app even when POST is an allowed method on the API. #1533

Closed
shwetachitlangia opened this issue Jan 7, 2018 · 34 comments

Comments

@shwetachitlangia
Copy link

shwetachitlangia commented Jan 7, 2018

Moya version ->10.0.1

I am made a LoginAPI class with following method implementation.

public var method: Moya.Method {
        return .post
    }

The Login Service allows only POST HTTP method.
The issue is even after specifying Moya method as POST, the service response returns 405 status code in service call first time. If I retry the same call, status code 200 is returned.

Logs with 405 status code:
Request: https://myURL/login
Moya_Logger: [07/01/2018 21:08:54] Request Headers: ["Content-Type": "application/json"]
Moya_Logger: [07/01/2018 21:08:54] HTTP Request Method: POST
Moya_Logger: [07/01/2018 21:08:54] Request Body: {"password”:”password”,”email”:”abc@del.com"}
Moya_Logger: [07/01/2018 21:08:54] Response: <NSHTTPURLResponse: 0x608000038ac0> { URL: Request: https://myURL/login } { Status Code: 405, Headers {
Allow = (
POST
);
Date = (
"Sun, 07 Jan 2018 15:35:42 GMT"
);
"Transfer-Encoding" = (
Identity
);
} }

Logs with 200 Status code:
Request: https://myURL/login
Moya_Logger: [07/01/2018 21:12:35] Request Headers: ["Content-Type": "application/json"]
Moya_Logger: [07/01/2018 21:12:35] HTTP Request Method: POST
Moya_Logger: [07/01/2018 21:12:35] Request Body: {"password”:”password”,”email”:”abc@del.com"}
Moya_Logger: [07/01/2018 21:12:38] Response: <NSHTTPURLResponse: 0x60400043ab80> { URL: Request: https://myURL/login } { Status Code: 200, Headers {
"Content-Type" = (
"application/json;charset=UTF-8"
);
Date = (
"Sun, 07 Jan 2018 15:39:26 GMT"
);
"Transfer-Encoding" = (
Identity
);
} }

Points to note:

  1. This url works perfectly in Postman everytime with 200 status code with POST method.
  2. On simulator, this is the behavior first time I run the app (fresh launch of the app). On next run or on retrying , it works.
  3. Tested the api call by refactoring it to an Alamofire call, it works.

Could someone please help with what could be the possible cause for this?

@zhongwuzw
Copy link
Member

Can you capture the packet when you request Post first time? Provide it can found the issue more specifically if you provide HTTP content.

@LavareX
Copy link
Member

LavareX commented Jan 8, 2018

@shwetachitlangia Please fill in the appropriate title, help others quickly understand your problem. :]

@shwetachitlangia shwetachitlangia changed the title 5 Status code 405 returned for the first POST call of the app eben when POST is an allowed method on the API. Jan 8, 2018
@shwetachitlangia shwetachitlangia changed the title Status code 405 returned for the first POST call of the app eben when POST is an allowed method on the API. Status code 405 returned for the first POST call of the app even when POST is an allowed method on the API. Jan 8, 2018
@shwetachitlangia
Copy link
Author

shwetachitlangia commented Jan 8, 2018

@zhongwuzw Sorry, I am unable to track packets using Wireshark. But i rewrote the same api call with Alamofire and tested with same conditions, it works.

The issue seems to be with the First POST operation of the app.
The first GET operations works just fine.

@AndrewSB
Copy link
Member

AndrewSB commented Jan 8, 2018

@shwetachitlangia without more information it's going to be hard to help you debug your issue. This would be a massive bug in Moya if it is an issue with Moya, but (from the fact that hundreds, if not thousands of apps are in production with Moya) it's more likely an issue with your code than the library.

Do you think you can make a Playground/example project that shows the issue? Without wireshark logs that would be most helpful for us to get your bug sorted out.

@shwetachitlangia
Copy link
Author

Can this code help?
Doesn't seem like a code issue as we are calling the same API again and it works.
Cannot share an example project as we have secured services.

//-------------------------------------------------------------------------
// Login APIs - Login user
//-------------------------------------------------------------------------

import Moya

let loginProvider = NetworkUtility.getMoyaProvider(LoginAPI.self)

public enum LoginAPI {
    case loginUser([String: Any])
    case forgotPasswordOTP(String)
    case resetPassword([String: Any])
}

extension LoginAPI: TargetType {

    public var baseURL: URL { return URL(string: ConfigData.shared.getURL(forKey: DefaultsKeys.baseURL))! }

    public var path: String {
        switch self {
        case .loginUser:
            return ConfigData.shared.getURL(forKey: DefaultsKeys.login)
        case .resetPassword:
            return ConfigData.shared.getURL(forKey: DefaultsKeys.resetPassword)
        case .forgotPasswordOTP:
            return ConfigData.shared.getURL(forKey: DefaultsKeys.forgotPasswordOTP)
        }
    }

    public var method: Moya.Method {
        switch self {
        case .loginUser:
            return .post
        case .resetPassword, .forgotPasswordOTP:
            return .put
        }
    }

    public var task: Task {
        switch self {

        case .loginUser(let bodyParameters),
              //UserLogin dictionaryRepresentation is used for this
             .resetPassword(let bodyParameters):
            return .requestCompositeParameters(bodyParameters: bodyParameters,
                                               bodyEncoding: JSONEncoding.default,
                                               urlParameters: [:])
        case .forgotPasswordOTP(let email):
            return .requestCompositeParameters(bodyParameters: [User.Keys.email: email],
                                               bodyEncoding: JSONEncoding.default,
                                               urlParameters: [:])
        }
    }

    public var headers: [String: String]? {
        return NetworkUtility.getHeaders()
    }

    public var sampleData: Data {
        var data: Data! = nil
        switch self {
        case .loginUser:
            data = NetworkUtility.loadJSON(jsonName: "3.33.4Success")
        case .resetPassword:
            data = NetworkUtility.loadJSON(jsonName: "ResetPassword")
        case .forgotPasswordOTP:
            data = NetworkUtility.loadJSON(jsonName: "VerifyUser")
        }
        return data
    }
}

@LavareX
Copy link
Member

LavareX commented Jan 9, 2018

@shwetachitlangia The above code snippet provides insufficient information. Or you can request third-party public services (for example: https://httpbin.org), see the test will appear the same problem? In order to troubleshoot the problem.

@karbhasin-zz
Copy link

@yangcaimu Facing exactly the same issue. Sending the following POST request -

Request: http://XXXXXX/YYYY/UUUIIUIIUIUIUIUIU
Moya_Logger: [15/01/2018 16:10:08] Request Headers: ["Content-Type": "application/json", "correlationId": "876578658769389283kjhgf"]
Moya_Logger: [15/01/2018 16:10:08] HTTP Request Method: POST
Moya_Logger: [15/01/2018 16:10:08] Request Body: {"password":"password","email":"shshs@sd.com"}..

Checked with server team, as per their logs, they are getting method type as "ST" instead of POST.

AS per Server Logs -
"o.s.web.servlet.DispatcherServlet - DispatcherServlet with name ‘dispatcherServlet’ processing ST request for [/YYYY/UUUIIUIIUIUIUIUIU]"

@zhongwuzw
Copy link
Member

@karbhasin , strange behavior, maybe the only solution is to get requests raw packet from client-side and server-side, then compare them to find the issue.

@aloco
Copy link
Contributor

aloco commented Jan 17, 2018

Hi,

I am updating a project from Moya 7.0.0 (swift 2.x) to Moya 10.0.0, facing the same issue. @shwetachitlangia did you find any workarounds?

@sunshinejr
Copy link
Member

This is really strange and unfortunately all of you guys can't share your project to help us investigate it, right?

In that case, will any of you guys (@aloco, @karbhasin, @shwetachitlangia) want to make a quick call with me and we could try debug it on the fly? Being able to reproduce it and access to the server logs would be awesome.

@shwetachitlangia
Copy link
Author

shwetachitlangia commented Jan 17, 2018

@sunshinejr I can have a call with you. I can reproduce it. But don't have access to server logs.
My skype id is chitstcs.

@SD10
Copy link
Member

SD10 commented Jan 17, 2018

@shwetachitlangia Did this issue occur after a migration to 10.0.1? If so, what was the previous Moya version where this issue was not present?

Sent with GitHawk

@shwetachitlangia
Copy link
Author

@SD10 we have started facing this issue from 10.0.0

@aloco
Copy link
Contributor

aloco commented Jan 19, 2018

Hi, trying to investigate the issue but it seems very strange to me. First it doesn´t happen with every POST request every time and secondly I just ran into the same issue with a DELETE call.

  "status" : 405,
  "message" : "Request method 'LETE' not supported",
  "timestamp" : 1516355038187,
  "exception" : "org.springframework.web.HttpRequestMethodNotSupportedException",

The request setup looks correct since MoyaLogger prints the request correctly. I think this happens also only with long url´s @shwetachitlangia can you confirm this?

@sunshinejr
Copy link
Member

Can you guys check with a proxy (like mitmproxy) to see if the request seems to be okay there as well?

@AndrewSB
Copy link
Member

@shwetachitlangia did this issue not show up on an earlier version? 9.x, for example?

@shwetachitlangia
Copy link
Author

@AndrewSB Yes, did not face it with 9.x.
The issue doesnot happen with every POST request.
If we hit one GET followed by a POST request, the POST fails with 405.

@shwetachitlangia
Copy link
Author

@aloco So, the issue is "POST" becomes "ST" and "DELETE" becomes "LETE".
The first two chars are truncated making it an invalid HTTP method.
Can anyone know the possible reason for this?

@zhongwuzw
Copy link
Member

@shwetachitlangia I think only two reasons, one is iOS network system bug? because the http method like getpost.. appended on packet by system automatically . Another reason is server-side, truncated first two bytes when handle http. So as I said as before, only method to figure out is to catch network packets.

qq20180120-132129 2x

@strikernani
Copy link

Hi All,
I was getting same issue.I have updated Moya version to the 10.0.1(it was 8.0.3).
At the first time I got issue with the headers in the target type.
I added the headers
public var headers: [String : String]? { let assigned: [String: String] = ["Content-Type": "application/json"] return assigned }
After that I got the issue with public var task: Task
In 8.0.3 Task Extension has only .request upload
In 10.0.3 `case requestPlain

/// A requests body set with data.
case requestData(Data)

/// A request body set with `Encodable` type
case requestJSONEncodable(Encodable)

/// A requests body set with encoded parameters.
case requestParameters(parameters: [String: Any], encoding: ParameterEncoding)`

So compare to both in 8.0.3 version request is handling entire .get and .post
In 10.0.3 version

`case requestPlain

/// A requests body set with data.
case requestData(Data)

/// A request body set with `Encodable` type
case requestJSONEncodable(Encodable)

/// A requests body set with encoded parameters.
**case requestParameters(parameters: [String: Any], encoding: ParameterEncoding)**`

Now the final result is
My Task extension is
` public var task: Task {

parameters coming from the extension

    if parameters?.count != nil
    {
        return .requestParameters(parameters: parameters!, encoding: JSONEncoding.default)
    }else{
        return .requestPlain

    }
}`

` public var parameters: [String: Any]? {
switch self {

    case .getData(_ , let dicParams):
        return dicParams
    case .postLoginDetails(_, let dicParams):
        return dicParams

}`

Hope it will be helpful Thanks..

@SD10 SD10 added the bug? label Jan 24, 2018
@SD10
Copy link
Member

SD10 commented Jan 24, 2018

It looks like we have 4 people experiencing this issue and they mention it wasn’t present in Moya 8.0. We refactored the Task object in Moya 9.0.

Can anyone who is experiencing the issue put together an example project that replicates it?

Tagging @Dschee in case he can give any insight

Sent with GitHawk

@Jeehut
Copy link
Contributor

Jeehut commented Jan 24, 2018

I've read through the thread, but I can't remember anything that might cause this error related with the refactoring of Task. Also the code was refactored quite a bit after me implementing the initial feature.

What I'd suggest the people seeings this issue to do:

  1. Downgrade to Moya 10.0.0 and see if the issue is there, still.
  2. Downgrade to Moya 9.0.0, possibly reverse-migrate your code if needed, then try that.

This way we can isolate the time frame the issue was introduced more exactly.

@aloco
Copy link
Contributor

aloco commented Jan 24, 2018

I tried mitmproxy but facing other issues with using the proxy (getting some timeouts 🤷‍♂️), will dig into it more when I find time, but so far, I haven´t seen the issue when using the proxy but don´t take my attempt as too meaningful as I tested this not excessively and sometimes the issue doesn´t show up, even without the proxy.

@strikernani
Copy link

strikernani commented Jan 24, 2018

@Dschee Thanks...
I have three type of services in the same project.
Query Params and Path Params as GET
POST data with body.

I have written code like this in the Task it is absolutely working fine with the 10.0.1 version of Moya.

Here is my code.

` public var task: Task {

    switch self {
    case .getInboxMessages(_):
        return .requestCompositeData(bodyData: Data(), urlParameters: parameters!)
    case .getMembersList(_, _):
        return .requestCompositeData(bodyData: Data(), urlParameters: parameters!)

    default:

        if parameters?.count != nil
        {
            return .requestParameters(parameters: parameters!, encoding: JSONEncoding.default)
        }else{
            return .requestPlain

        }

    }
    
    
}`

@SD10 May I know the above logic is perfect or anything wrong.Now I am getting my results perfectly, However I need to check my entire project...
-- 😌

@shwetachitlangia
Copy link
Author

These are the server logs -
WARN 1885 --- [o-8081-exec-453] o.s.web.servlet.PageNotFound : Request method 'ST' not supported

@strikernani
Copy link

'ST' means...? it should be 'POST' right?
Can u pls share your code how you are sending data.
Which version are you using..?

@SD10
Copy link
Member

SD10 commented Feb 14, 2018

How many people are using Spring here?

@shwetachitlangia
Copy link
Author

@SD10 Yes, the Services team is using Spring Boot.

@stale
Copy link

stale bot commented Mar 1, 2018

This issue has been marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@stale stale bot added the stale label Mar 1, 2018
@SD10
Copy link
Member

SD10 commented Mar 1, 2018

I suspect this issue is unrelated to Moya and is in fact a problem with Spring. Going to ask Mr. Stalebot to keep this open

Sent with GitHawk

@stale stale bot removed the stale label Mar 1, 2018
@stale
Copy link

stale bot commented Mar 15, 2018

This issue has been marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@stale stale bot added the stale label Mar 15, 2018
@stale
Copy link

stale bot commented Mar 22, 2018

This issue has been auto-closed because there hasn't been any activity for at least 21 days. However, we really appreciate your contribution, so thank you for that! 🙏 Also, feel free to open a new issue if you still experience this problem 👍.

@wongwenlei
Copy link

I also encountered the same problem. After deleting the unused case in enum, the problem is solved. I don't know why.

@dj-ya
Copy link

dj-ya commented Jul 25, 2019

I had this problem on react-native app (ios)
My solution for fix:
when i config axios request i set field DATA as null, not emply object {} !!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests